Non-Interactive Mode
When no command is written to a chip, it will automatically generate a random challenge and sign it using key slot #2 while incrementing a counter. For chips with this feature you cannot request signatures of external data from key slot #2.
⚠️
Experimental feature available in version c3
or greater. Interface is expected to change.
Verification Example
Using the URL below, we can verify the randomly generated challenge against the secondary public key of the HaLo:
- Scan the HaLo chip and parse the NDEF record. The
static
parameter contains the public key for key slot #2 orpkey2
.
static
41 04BDC6288D344F129820317411D8A8283942DCDB4B2D2F86E78F22F944160B6038C9E8DC747710349C2E55E6BC52D8745B749B39051BF72A0307B339257A48AECF
- When there was no command initiated, the
cmd
parameter includes acommand code
andchallenge
:
command code
: 2 bytes (always: 8102).challenge
: 32 bytes (e.g. 00000009DC18…), which consists of:- Big-endian UInt32: incremental counter, increases by 1 on each tap.
- Random 28 bytes: random number generated by the chip on each tap.
- Zero-padding: 1 byte (always: 00).
cmd
8102 00000002F202C592C809428C2C763C3AB3A4BBF5475DD4567A45F8200E82C63D 00
- Parse the
res
parameter includes the ECDSA signature:
res
30450221009FB0D4E3F7BF343219E4A8779059412E3E1A2F26EAAE69B6246EA1AD118D3EE40220783DEBF12DF1D60DF6488543C8100937E9A596028B2D97D65279378713157CF1 0000000000
- Verify the ECDSA signature against the publick key and challenge:
const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
let pkey2 = "04BDC6288D344F129820317411D8A8283942DCDB4B2D2F86E78F22F944160B6038C9E8DC747710349C2E55E6BC52D8745B749B39051BF72A0307B339257A48AECF";
let challenge = "00000002F202C592C809428C2C763C3AB3A4BBF5475DD4567A45F8200E82C63D";
let signature = "30450221009FB0D4E3F7BF343219E4A8779059412E3E1A2F26EAAE69B6246EA1AD118D3EE40220783DEBF12DF1D60DF6488543C8100937E9A596028B2D97D65279378713157CF1";
let key = ec.keyFromPublic(pkey2.toString('hex'), 'hex');
if (!key.verify(challenge, signature)) {
return {"error": "Unable to verify HaLo signature."};
}
Note that unlike typical Ethereum messages, the random number is not keccak256
hashed prior to being signed.