WorkingRegister
This object is used by the script interpreter as working space
and may be used in a transaction script. This object is automatically
created when the transaction group is created. It is a private
object and cannot be read using the ReadObject command. There
may only be one Working Register object in a transaction group.
ROMData
This object is automatically created when the transaction group
is created. It is a locked object and cannot be altered using
the write object command. This object is eight bytes in length
and its contents are identical to the eight byte ROM Data of the
Crypto iButton. There may only be one ROM Data object in a transaction
group.
RandomFill
When the script interpreter encounters this type of object it
automatically pads the current message so that its length is 1
bit smaller than the length of the following modulus. This object
is automatically created when the transaction group is created.
It is a private object and may not be read using the read object
command. There may only be one Random Fill object in a transaction
group.
Modulus
A modulus object is a large integer of at most 128 bytes in length.
It must be used by scripts, which perform modular exponentiations.
Exponent
An exponent object is (typically) a large integer of at most 128
bytes in length. It is used as the exponent value in modular exponentiations.
Money
The money object may be used to represent money or some other
form of credit. Once this object has been created it must be locked
to prevent a user from tampering with its value. Once locked only
invoking a transaction script can alter the value of this object.
A typical transaction group, which performs monetary transactions,
might have one script for withdrawals from the money register
and one for deposits to the money register.
Counter
The counter object is usually initialized to zero when it is created.
Every time a transaction script, which references this object,
is invoked, the transaction counter increments by 1. Once a transaction
counter has been locked it is read only and provides an irreversible
counter.
Script
A script is a series of instructions to be carried out by the
Crypto iButton's script interpreter. When invoked the Crypto iButton
firmware interprets the instructions in the script and typically
places the results in the output data object (see above). The
actual script is simply a list of objects and valid script operators.
Scripts may be as long as 128 bytes and may be continued as long
as needed.
ClockOffset
This object is a 4-byte number, which contains the difference
between the reading of the Crypto iButton's real-time clock and
some convenient time (e.g. 12:00AM, January 1, 1970). The true
time can then be obtained from the Crypto iButton by adding the
value of the clock offset to the real-time clock.
SALT
A SALT (random challenge) object is simply a large random number.
When the script interpreter encounters a SALT object on the right-hand
side of an assignment operator a new random number replaces its
value.
Configuration
This is a user-defined structure with a maximum length of 128
bytes. This object is typically used to store configuration information
specific to its transaction group. For example, the configuration
data object may be used to specify the format of the money register
object (i.e. the type of currency it represents). This object
has no pre-defined structure.
InputData
An input data object is simply an input buffer with a maximum
length of 128 bytes. The host uses input data objects to store
data to be processed by transaction scripts.
Destructor
A destructor object is 4 bytes in length and is initialized to
some value greater than the Crypto iButton's real time clock.
When the script interpreter is called it checks the group to see
if it contains a destructor. If it does, it checks the script
itself, and all objects referenced in the script to see if they
are destructible. If any of the objects are destructible, the
script interpreter compares the value of the destructor with the
value of the real time clock. If the value in the clock is greater
than the destructor's value, the script interpreter terminates
the script with the ERR_DESTRUCTED_OBJECT error code. There may
only be one destructor object in a transaction group.
End
Used to specify the end of the script implementation or the object
declaration section.
Open
Used to specify the start of the list of open objects.
Locked
Used to specify the start of the list of locked objects.
Private
Used to specify the start of the list of private objects.
TransactionGroup
Usually the 1st line of a group source file. The TransactionGroup
line specifies the group name.
Script
As well as being an object type, the reserved word script
is used in the implementation section to specify the beginning
of the script code.
Note that all object types are reserved words. A list of object types and their definitions appears in Appendix A.
If, Then and Else
Used to test a condition and jump to an offset determined by the
result of the test.
Continue
Used to jump from one script to another script contained within
the same group.
Goto
Used to jump to a label contained within the same script.
Exit
Aborts execution of a script and returns a user-defined error
code.
Replace, With
The Replace With statement is used to associate a numerical constant
with a name.
Error Code | Value | Description |
ERR_OPERATOR_NOT_EXPECTED | C0H | Returned when an operator was misused. |
ERR_EOS_EXPECTED | C1H | An end of statement (;) was expected but was not found. |
ERR_BAD_ID | C2H | An object that did not exist was referenced within the script. |
ERR_NOT_COMPOSITE | C3H | Returned when the member of (.) operator references an embedded object which may not contain embedded objects. |
ERR_UNEXPECTED_END | C4H | Returned when a statement ends unexpectedly. |
ERR_NOT_AN_OPERATOR | C5H | Returned when an operator was expected, but no operator was found. |
ERR_BAD_TYPE | C6H | The first byte after the member of (.) operator must be an object type specification byte. If it is not a valid type byte, the script interpreter will return this error code. |
ERR_MEMBER_NOT_FOUND | C7H | The script interpreter could not find the embedded object referenced by the member of (.) operator. |
ERR_BAD_COMPARE | C8H | The left and right values of a comparison statement were not identical. |
ERR_BAD_ADDITION | C9H | An overflow occurred while adding 2 objects. |
ERR_BAD_SUBTRACTION | CAH | An underflow occurred while subtracting 2 objects. |
Error Code | Value | Description |
ERR_SIZE | CBH | A size mismatch error has occurred. This error code is usually returned when the interpreter is instructed to move an object into another object with a smaller data field. |
ERR_NOT_EXPONENT | CDH | The object id of an exponent did not follow the exponentiation (^) operator |
ERR_NOT_MODULUS | CEH | The object ID of a modulus did not follow the modulus (Mod) operator. |
ERR_MOD_OP_EXPECTED | CFH | The exponentiation (^) operator and the object ID of an exponent were found, but not followed by the modulus (Mod) operator and the ID of a modulus. |
ERR_OBJECT_DESTRUCTED | D0H | Before the script interpreter begins executing the instructions within the script, it checks all of the objects referenced by the script to make sure they have not become inactive. For an object to be inactive it must be a destructible object and the group must contain a destructor whose value is less than that of the real time clock. |
ERR_CIB_INACTIVE | D1H | The Crypto iButton's activation period has expired. This implies the real time clock's value has exceeded that of the group 1 destructor. |
ERR_FUNCTION_CALL | D2H | An error occurred within the function library. This is typically caused by invalid parameters being passed to a function. |
ERR_PARAMETER_COUNT | D3H | An incorrect number of parameters were supplied to a function. |
ERR_GOTO | D4H | The offset following a goto was invalid. |
ERR_NOT_SCRIPT | D5H | The object ID supplied in a continue statement was not the ID of a script object. |
ERR_BAD_ELSE | D6H | The offset specified in an else statement was out of range. |
All bold characters are the actual characters used in an argument, all italicized characters/strings indicate variables and all parameters contained [within square brackets] are optional.
Pre-processor group arguments
P(b1 b2 bm-1 bm) | - initialize with the byte sequence b1
bm, bytes are separated by commas or white space, |
P'password' | - Set group password to password. |
Pre-processor object arguments
B | - Button created. | {default: no} |
Sn | - Object size = n, 0 < n <129. | {default: n=1} |
I(Rl1) or I(1)[n1] or I1[n1]- Initial data.
{Rl | - initialize with random data, [l random bytes] |
(=b1 bm) | - initialize with the byte sequence b1
bm, [repeated n times] bytes are separated by commas or white space, |
(='string') | -
initialize with the string string, [n times] - default: all bytes initialized with zero} |
C(CompositeData1 or InitialData1[[;CompositeData2 or InitialData2] [CompositeDatam or InitialDatam]])
{CompositeDatai = typei, leni [, InitialDatai]}
Composite entries can be either CompositeData, which specifies the type type, length len and optional initialization data InitialData or simply InitialData, which does not contain the type or length information.
Composite Object Example
ConfigInfo = $04 {+ S45 C(ROMData, 8, I(0)8;
{Configuration object (with ObjectId 4), 45 bytes in length with 8 bytes of RomData, initialized to 0, 17 bytes of input data initialized to 'Special Project 1' and a 20 byte Salt initialized with random data}
Symbol File Example
{+ P'password' -} | |
{User objects} | |
PrivateExponent | =$01 {+ S128 B -} |
PublicExponent | =$02 {+ S128 B -} |
MyModulus | =$03 {+ S128 B-} |
ConfigInfo | =$04 {+ S45 C(ROMData,8,I(0)8;
SALT,$14,I(R$14)) -} |
Input1 | =$05 {+ S128 I(0)128 -} |
EncryptScript | =$06 {Script information generated by compiler} |
{Auto Objects} | |
Output | =$A0 |
Functions: | |
SHA1 | =$01 |
SHA1 | Function code (01) |
Hash := SHA1(Message); |
The parameter passed to SHA1 must be an object ID and not a reference to a composite object. The following statement is not supported.
Hash := SHA1(Input.Configuration[1]); |
ToBCD | Function code (02) |
BCDOut := ToBCD(BinBalance); |
The parameter passed to ToBCD must be an object ID and not a reference to a composite object.
ToBin | Function code (03) |
BinOut := ToBin(BCDBalance); |
The parameter passed to ToBin must be an object ID and not a reference to a composite object.
MD5 | Function code (04) |
Hash := MD5(MessageData, HashVal, BlockCount, LastMessage); |
MessageData is the object ID of the data to be hashed. If this is not the last block(s) of the entire message, the length of MessageData must be either 64 or 128 bytes. When MD5 is called with the final block of the message the length of MessageData can be any valid object length.
HashVal is the object ID of the object containing the initial hash value. When MD5 is called with the 1st block(s) of the message the ID passed for HashVal must be 0.
BlockCount is the object ID of the block counter. This is typically a locked configuration object. When MD5 is called with the 1st block(s) of message data the contents of the BlockCount object are automatically initialized.
LastMessage is either a 0 or a 1. If the current call to MD5 does not contain the last block(s) of the message, LastMessage must be 0. Otherwise LastMessage must equal 1.
The following code sample hashes the contents of 2 objects and places the resutt in the output object named Hash.
Temp := MD5(Input1, 0, BlockCount, 0); Hash := MD5(Input2, Temp, BlockCount, 1); |
There is no practical limit on the total length of the message hashed using the MD5 function.
TransactionGroup('Digital Notary'); {
Begin
Certificate, Plain: OutputData; RSAMod: Modulus; ExecCnt: Counter; TimeStamp: ClockOffset; SerId: ROMData;
Temp: WorkingRegister; Pad : RandomFill; Script DigitalNotary;
Begin
Plain := Temp; Temp <- SHA1(Temp); Certificate := (Temp & Pad)^ SecretExp Mod RSAMod; |
The first assignment statement begins by copying Msg into Temp as an embedded object. ExecCnt is then incremented by 1 and the result is appended to Msg. TimeStamp is a clock-offset object. When a clock-offset object is referenced on the right side of an assignment operator, the interpreter adds the clock offset value to current value of the real time clock. The result is then appended to temp. Note that when ExecCnt is referenced its value is changed. However the value of TimeStamp is not altered. The first assignment statement concludes by appending the Crypto iButton's serial number to the other 3 objects embedded in Temp. Next the contents of temp are copied to a readable output data object to be used in the signature verification process.
The next statement hashes the intermediate value and reuses the temp object to hold the result of the hash function. Finally the resulting hash value is padded with random data and signed using the group's secret RSA exponent.
Example 2: Electronic Purse
This sample group maintains a monetary balance in a money register
using two scripts. One script is used for deposits and the other
for withdrawals. The deposit script is made destructible to prevent
refill of the money register after a pre-specified period of time.
TransactionGroup('Checkbook'); {
Begin
Withdrawal: Script; Challenge: SALT; Time: ClockOffset; RSAMod, VendorMod: Modulus; VendorPub: Exponent; SerId: ROMData; LifeSpan: Destructor; Plain, Signed: OutputData;
Temp: WorkingRegister; Pad: RandomFill;
Script Deposit; Destructible;
Begin
Temp := Request ^ VendorPub Mod VendorMod; { Make sure the challenge was successfully met } Temp.Salt[1] = Challenge; { Generate a new random challenge } Challenge := Challenge; Balance := Balance + Temp.Money[1];
Script Withdrawal;
Begin
Plain := Request & SerId & Time; Signed := (SHA1(Plain) & Pad) ^ SecretExp Mod RSAMod; |
The deposit script decrypts the request certificate using the vendor's public key and checks the SALT object embedded in the resulting plaintext. If it matches the value of the Challenge object, a new value of Challenge is generated and the money register is increased by the amount indicated in the embedded money object. Note that line 4 (Challenge := Challenge;) of this script is required to avoid packet replay. Each time a random challenge is successfully signed a new random challenge must be generated.