变更记录

  • 2022 年 10 月 3 日:初始草案

状态

草案

摘要

本附录提供了关于设备应如何渲染 SIGN_MODE_TEXTUAL 文档的规范性指导。

背景

SIGN_MODE_TEXTUAL 允许在硬件安全设备上对交易的可读版本进行签名,例如 Ledger。该设计的早期版本会直接将交易渲染为多行 ASCII 文本,但这在带内信号表达方面较为别扭,同时也难以满足在交易中显示 Unicode 文本的需求。

决策

SIGN_MODE_TEXTUAL 会渲染为一种抽象表示,至于如何根据设备的能力、限制和约定来展示这一表示,则由设备特定的软件决定。 我们给出如下规范性指导:
  1. 在设备能力允许的前提下,展示内容应尽可能便于用户阅读。如果需要为了其他特性牺牲可读性,我们建议直接使用其他签名模式。可读性应优先面向常见场景;对于不常见的场景,可读性稍差是可以接受的。
  2. 如果不需要显著牺牲可读性,展示内容应尽可能可逆。对渲染数据的任何修改,都应导致展示内容发生可见变化。这将签名的完整性扩展到了用户可见的展示层面。
  3. 展示内容应遵循设备的常规约定,但不能以牺牲可读性或可逆性为代价。
为了说明这些原则,下面给出一个示例算法,适用于只能显示单行 80 个可打印 ASCII 字符的设备:
  • 展示内容会被拆分为多行,并按顺序逐行展示,用户可以通过控制操作前进或后退一行。
  • 只有当设备处于专家模式时,才会显示专家模式界面。
  • 屏幕上的每一行都会先输出若干个 > 字符,其数量等于该屏幕的缩进级别;如果这不是该屏幕的第一行,则再输出一个 + 字符;如果已经输出了 > 或 +,或者该头部后面紧跟着 >、+ 或空格,则再输出一个空格。
  • 如果一行以空白字符或 @ 字符结尾,则会在该行末尾额外追加一个 @ 字符。
  • 以下 ASCII 控制字符或反斜杠(\)会被转换为反斜杠加字母代码,其方式与许多语言中的字符串字面量类似:
    • a:U+0007 alert 或 bell
    • b:U+0008 backspace
    • f:U+000C form feed
    • n:U+000A line feed
    • r:U+000D carriage return
    • t:U+0009 horizontal tab
    • v:U+000B vertical tab
    • \:U+005C backslash
  • 其他所有 ASCII 控制字符,以及非 ASCII 的 Unicode 码点,将按以下两种方式之一显示:
    • 对于基本多文种平面(BMP)中的码点,显示为 \u 后接 4 个大写十六进制字符。
    • 对于其他码点,显示为 \U 后接 8 个大写十六进制字符。
  • 屏幕内容会被拆分为多行以适应 80 字符限制,并在考虑上述转换规则的前提下尽量减少生成的行数。展开后的控制字符或 Unicode 字符绝不会在行之间被拆开。
示例输出:
An introductory line.
key1: 123456
key2: a string that ends in whitespace   @
key3: a string that ends in  a single ampersand - @@
 >tricky key4<: note the leading space in the presentation
introducing an aggregate
> key5: false
> key6: a very long line of text, please co\u00F6perate and break into
>+  multiple lines.
> Can we do further nesting?
>> You bet we can!
逆向映射可得出唯一可能生成该输出的输入(字符串数据使用 JSON 记法):
Indent  Text
------  ----
0       "An introductory line."
0       "key1: 123456"
0       "key2: a string that ends in whitespace   "
0       "key3: a string that ends in  a single ampersand - @"
0       ">tricky key4<: note the leading space in the presentation"
0       "introducing an aggregate"
1       "key5: false"
1       "key6: a very long line of text, please coöperate and break into multiple lines."
1       "Can we do further nesting?"
2       "You bet we can!"

Changelog

  • Oct 3, 2022: Initial Draft

Status

DRAFT

Abstract

This annex provides normative guidance on how devices should render a SIGN_MODE_TEXTUAL document.

Context

SIGN_MODE_TEXTUAL allows a legible version of a transaction to be signed on a hardware security device, such as a Ledger. Early versions of the design rendered transactions directly to lines of ASCII text, but this proved awkward from its in-band signaling, and for the need to display Unicode text within the transaction.

Decision

SIGN_MODE_TEXTUAL renders to an abstract representation, leaving it up to device-specific software how to present this representation given the capabilities, limitations, and conventions of the deivce. We offer the following normative guidance:
  1. The presentation should be as legible as possible to the user, given the capabilities of the device. If legibility could be sacrificed for other properties, we would recommend just using some other signing mode. Legibility should focus on the common case - it is okay for unusual cases to be less legible.
  2. The presentation should be invertible if possible without substantial sacrifice of legibility. Any change to the rendered data should result in a visible change to the presentation. This extends the integrity of the signing to user-visible presentation.
  3. The presentation should follow normal conventions of the device, without sacrificing legibility or invertibility.
As an illustration of these principles, here is an example algorithm for presentation on a device which can display a single 80-character line of printable ASCII characters:
  • The presentation is broken into lines, and each line is presented in sequence, with user controls for going forward or backward a line.
  • Expert mode screens are only presented if the device is in expert mode.
  • Each line of the screen starts with a number of > characters equal to the screen’s indentation level, followed by a + character if this isn’t the first line of the screen, followed by a space if either a > or a + has been emitted, or if this header is followed by a >, +, or space.
  • If the line ends with whitespace or an @ character, an additional @ character is appended to the line.
  • The following ASCII control characters or backslash (\) are converted to a backslash followed by a letter code, in the manner of string literals in many languages:
    • a: U+0007 alert or bell
    • b: U+0008 backspace
    • f: U+000C form feed
    • n: U+000A line feed
    • r: U+000D carriage return
    • t: U+0009 horizontal tab
    • v: U+000B vertical tab
    • \: U+005C backslash
  • All other ASCII control characters, plus non-ASCII Unicode code points, are shown as either:
    • \u followed by 4 uppercase hex chacters for code points in the basic multilingual plane (BMP).
    • \U followed by 8 uppercase hex characters for other code points.
  • The screen will be broken into multiple lines to fit the 80-character limit, considering the above transformations in a way that attempts to minimize the number of lines generated. Expanded control or Unicode characters are never split across lines.
Example output:
An introductory line.
key1: 123456
key2: a string that ends in whitespace   @
key3: a string that ends in  a single ampersand - @@
 >tricky key4<: note the leading space in the presentation
introducing an aggregate
> key5: false
> key6: a very long line of text, please co\u00F6perate and break into
>+  multiple lines.
> Can we do further nesting?
>> You bet we can!
The inverse mapping gives us the only input which could have generated this output (JSON notation for string data):
Indent  Text
------  ----
0       "An introductory line."
0       "key1: 123456"
0       "key2: a string that ends in whitespace   "
0       "key3: a string that ends in  a single ampersand - @"
0       ">tricky key4<: note the leading space in the presentation"
0       "introducing an aggregate"
1       "key5: false"
1       "key6: a very long line of text, please coöperate and break into multiple lines."
1       "Can we do further nesting?"
2       "You bet we can!"