1. Abstract
This RFC specifies how a LanternSeaCoin (LSC) voucher can be carried on a magnetic stripe card and redeemed at a terminal.
A magnetic stripe is static and can be copied completely. The design therefore does not try to make the carrier secure. Instead it relies on four properties:
- the stripe carries a 128-bit voucher secret, and the issuer register stores only a commitment to it;
- a voucher is redeemed exactly once and only online;
- the face value is limited by the loss the issuer is willing to accept from a copied stripe;
- every second redemption attempt is detected and treated as clone evidence.
A voucher is backed by an LSC stamp (Reference Paper §5) and settles through the online redeem flow of RFC-001 §8. This RFC does not define payment cards, and a voucher is not a payment card.
2. Motivation
Magnetic stripe readers are widespread, cheap and accepted by many terminals. They can carry LSC value to places where no NFC device, chip card or smartphone is available.
A stripe has no secure element, no counter and no way to hide data. Copying it is trivial. A specification that pretends otherwise would be wrong. This RFC states the limits openly and bounds the damage:
- the loss from one copied voucher is at most its face value;
- the loss from a batch of n vouchers is at most n times the face-value limit;
- a database leak at the issuer does not allow redemption, because the register stores commitments, not secrets.
3. Terminology
| Term | Meaning |
|---|---|
| Voucher | A single-use claim on a fixed LSC amount, represented by a secret printed or encoded on a stripe |
Voucher secret k | 128-bit random value carried on the stripe |
Commitment C | H(enc(DOM_CL, k, issuer_id)), stored in the issuer register |
| Issuer register | Issuer-operated table of commitments with state, face value and validity |
| Backing stamp | The LSC stamp (non-movable coin) that funds the voucher |
| Redemption service | Issuer-operated online service that verifies and settles redemptions |
| Terminal | Certified or registered device with a magnetic stripe reader that submits redemption requests |
| Clone | A second physical or logical copy of the same stripe data |
p_clone | Probability that a stripe is copied before redemption; fixed at 1 in this RFC |
ε_M | Maximum expected loss per voucher that the issuer accepts |
H, enc | BLAKE2b-256 and the length-prefixed encoding of Reference Paper §14.1.2 |
4. Goals
This RFC aims to provide:
- a compact stripe record that fits common tracks;
- an issuer register that is safe against database leaks;
- single-use online redemption with idempotent retries;
- authenticated terminals;
- an explicit, formula-based value limit;
- detection of cloned stripes;
- compatibility with the RFC-001 stamp and online redeem model.
5. Non-goals
This RFC does not define:
- a payment card, a PAN layout or any use of payment networks;
- offline redemption of magnetic stripe vouchers;
- protection against copying of the stripe itself;
- a chip or NFC carrier (see RFC-001 and RFC-003);
- a consumer wallet or user interface standard;
- partial redemption or change (see Open Decisions).
6. Voucher Model
6.1 Backing
Every voucher is backed by a stamp S held by the issuer. The stamp is a non-movable coin (Reference Paper §5). Redemption executes the claim of S and a transfer to the redeemer address atomically, as in RFC-001 §8.3. The claim window of S MUST end no earlier than the voucher's valid_until.
6.2 Secret and commitment
At issuance the issuer generates k with a cryptographically secure random generator (128 bits). The register stores:
C = H( enc( DOM_CL, k, issuer_id ) ) DOM_CL = "LSC-CLAIMSECRET-v1"The register MUST NOT store k. Knowing C does not allow redemption. Guessing a valid k succeeds after q attempts with probability at most q · 2^-128.
6.3 Voucher record
| Field | Size | Meaning |
|---|---|---|
C | 32 bytes | commitment (register key) |
face_value | uint64 | amount in base units (10^8 per LSC) |
stamp_id | 8 bytes | backing stamp |
valid_until | uint64 | chain height after which the voucher expires |
state | enum | see §11 |
pin_tag | optional | PIN verifier (§8.3) |
pin_tries | uint8 | remaining PIN attempts |
7. Stripe Record Encoding
7.1 Carrier
The record is written in ISO/IEC 7811 style on one track. Typical capacities are 79 alphanumeric characters on track 1, 40 numeric characters on track 2 and 107 numeric characters on track 3. The record in §7.2 uses track 1; the record in §7.3 uses track 3. Track 2 is too small for a 128-bit secret in decimal form and MUST NOT be used.
The record MUST NOT follow a payment card PAN layout. The format code after the start sentinel MUST NOT be the code used for bank cards. Readers and software MUST treat the data as an LSC voucher, never as a card number.
7.2 Track 1 record (alphanumeric)
% F LSC1 ^ N ^ K ^ X ? LRC| Element | Size | Content |
|---|---|---|
% | 1 | start sentinel |
F | 1 | format code reserved for individual card issuers (see Open Decisions) |
LSC1 | 4 | protocol tag and version |
^ | 1 | field separator |
N | 1 | network code: m mainnet, t testnet |
K | 26 | k in Base32 (RFC 4648 alphabet, no padding); the 2 padding bits MUST be zero |
X | 4 | check characters (§7.4) |
? | 1 | end sentinel |
LRC | 1 | longitudinal redundancy check, as defined by the track format |
The record has 41 characters plus the LRC and fits in 79 characters.
7.3 Track 3 record (numeric)
; V N K = X ? LRCV is one digit (version, 1), N one digit (1 mainnet, 2 testnet), K is k as a zero-padded 39-digit decimal integer (2^128 is smaller than 10^39), X is four check digits. The record has 48 characters and fits in 107.
7.4 Check characters
chk = first 20 bits of H( enc("LSC-MSV-CHK-v1", version, net, k) )encoded as 4 Base32 characters (track 1) or as chk mod 10^4 in 4 digits (track 3). The check detects misreads. It is not a security mechanism.
7.5 Reader requirements
The reader MUST deliver raw track data. A reader that encrypts or masks track data in payment-card mode MUST be configured for raw output, or a non-payment reader MUST be used. The voucher record is not payment card data (Reference Paper §19.1, R1 does not apply to it), but the terminal MUST NOT log k, and it MUST show only the last 4 characters of K on any receipt or display.
8. Issuance
8.1 Creation
- Generate
k; computeC. - Create or reserve the backing stamp S for
face_value. - Write the register entry with state
ISSUED. - Encode and write the stripe (§7); verify it by reading it back.
- Destroy
kin the issuing system after the write.
8.2 Activation
A voucher is created inactive. It becomes ACTIVE through an activation call by an authorized point of sale. Redemption of an ISSUED voucher MUST fail with E_VOUCHER_INACTIVE. Activation limits the exposure of stolen, unsold stock.
8.3 Optional PIN
A voucher MAY have a PIN of 4 to 8 digits, issued separately from the stripe. The register stores a keyed verifier, not the PIN:
pin_tag = HMAC-SHA256( K_pin, enc( C, pin ) ) K_pin held in an HSMPIN entry MUST take place on a PIN entry device, never on a general-purpose keypad. The service allows 3 attempts; after the third failure the state becomes LOCKED, and only the issuer can unlock the voucher.
8.4 Face-value limit
Because a stripe is fully copyable, p_clone = 1. The issuer MUST limit the face value as follows (value rule of Reference Paper §20.9):
v_M <= ε_M / p_clone = ε_M (no PIN)
v_M' <= ε_M / ( tries / 10^d ) (PIN with d digits and `tries` attempts)With ε_M = 1 LSC as reference value, a voucher without PIN carries at most 1 LSC. With a 4-digit PIN and 3 attempts the guess probability is 3·10^-4 and the limit rises to about 3,333 LSC; an issuer SHOULD use a much lower value. The loss from a batch of n vouchers is at most n · v_M.
9. Redemption
9.1 Request
Redemption is online only. The terminal sends:
| Field | Meaning |
|---|---|
version, net | protocol version and network |
terminal_id | registered terminal identity |
ctr | terminal counter, strictly increasing |
k | voucher secret read from the stripe |
pin_block | optional encrypted PIN |
payout_address | address that receives the amount (merchant or customer) |
nonce | 8 random bytes |
terminal_sig | Ed25519 signature, tag LSC-MSV-REQUEST-v1, over all fields above |
The request identifier is
request_id = H( enc( net, C, terminal_id, nonce ) )The channel MUST use TLS 1.2 or later with authentication of the service. The terminal signature authenticates the request at application level.
9.2 Service procedure
The service MUST perform these steps in one durable transaction:
- Verify
terminal_sig; check that the terminal is registered and not revoked. - Check
ctragainst the highest counter seen forterminal_id. - Compute
Cfromk; look up the register entry (E_VOUCHER_UNKNOWNif absent). - If
request_idwas seen: return the stored result for identical payloads; returnE_REQUEST_REPLAYfor a different payload. - Check state, validity and, if present, the PIN.
- Set the state to
REDEEMEDand record the settlement intent (stamp S, payout address,face_value).
After the transaction commits, the service executes claim and transfer and retries until the transaction is included in a block. The voucher is consumed at commit. A failure of the payout never returns the voucher to ACTIVE; the issuer owes the payout.
9.3 Response
The service returns a status code (§13), the amount, a receipt reference and, once available, the transaction identifier. The response is final for the voucher but not for chain finality; the receipt MUST say so until the block is final (Reference Paper §16.5).
9.4 Idempotency
An identical request returns the identical result. A request with the same request_id and different content returns E_REQUEST_REPLAY. Terminals SHOULD retry after network failures with the same nonce.
10. Clone and Skimming Handling
A copy cannot be prevented. It is detected when a second redemption attempt arrives for a redeemed C. Then:
- the service returns
E_VOUCHER_CONSUMED; - it records
terminal_id, time and request for both attempts; - it raises a clone event for the issuer, who MAY revoke the remaining vouchers of the same batch or lot;
- the first committed redemption stays final.
Velocity limits SHOULD apply per terminal and per lot: a maximum number of redemptions per time window and a maximum total amount. Terminals that produce an unusual share of E_VOUCHER_CONSUMED results SHOULD be reviewed.
Exposure bound: for a lot of n vouchers with limit v_M, the maximum loss is n · v_M.
11. State Machines
ISSUED --activate--> ACTIVE --redeem--> REDEEMED
ACTIVE --3 wrong PINs--> LOCKED --issuer unlock--> ACTIVE
ISSUED | ACTIVE | LOCKED --valid_until passed--> EXPIRED
ISSUED | ACTIVE | LOCKED --revoke--> REVOKEDREDEEMED, EXPIRED and REVOKED are final. An expired voucher's backing stamp returns to the issuer's control.
12. Consensus and Governance Rules
Settlement MUST obey the existing consensus rules. The register and the redemption service are issuer systems and are not part of consensus. Only the claim and the transfer are on-chain operations. This RFC does not authorize anyone to alter canonical state. Corrections follow the existing governance mechanism (Reference Paper §9).
13. Error Codes
| Code | Meaning |
|---|---|
E_VERSION | Unsupported version |
E_NETWORK | Network mismatch |
E_FORMAT | Stripe record malformed (sentinels, lengths, padding bits) |
E_CHECKSUM | Check characters do not match |
E_SIGNATURE | Terminal signature invalid |
E_TERMINAL_UNKNOWN | Terminal not registered or revoked |
E_COUNTER | Terminal counter not increasing |
E_VOUCHER_UNKNOWN | No register entry for the commitment |
E_VOUCHER_INACTIVE | Voucher not activated |
E_VOUCHER_CONSUMED | Voucher already redeemed |
E_VOUCHER_EXPIRED | Validity ended |
E_VOUCHER_REVOKED | Voucher revoked |
E_VOUCHER_LOCKED | Locked after wrong PINs |
E_PIN_REQUIRED | PIN missing |
E_PIN_WRONG | PIN incorrect; remaining attempts are returned |
E_AMOUNT_LIMIT | Face value above the issuer limit |
E_REQUEST_REPLAY | Request ID reused with a different payload |
E_RATE_LIMIT | Velocity limit reached |
E_TEMPORARY | Temporary service failure |
14. Security Considerations
14.1 Copying and skimming
The stripe is fully copyable. This is accepted by design. The defences are the value limit (§8.4), activation (§8.2), optional PIN, validity limits, velocity limits and clone detection. A skimmer gains at most the face value per voucher, and only if it redeems before the owner.
14.2 Register leak
The register contains commitments only. An attacker who reads it cannot derive k, because the preimage is 128 bits of random data. The PIN verifier is keyed with an HSM key, so a leak does not allow offline PIN guessing.
14.3 Guessing
A guess hits a valid voucher with probability at most q · 2^-128. The service MUST rate-limit unknown-voucher lookups per terminal and per source.
14.4 Terminal compromise
A compromised terminal learns k of vouchers it reads, which are anyway on the stripe. Terminal signatures and registration prevent unregistered devices from submitting. A revoked terminal's requests MUST fail.
14.5 Replay and man-in-the-middle
Requests carry a terminal counter, a nonce and a signature, and travel over TLS. A replayed request returns the stored result and creates no second payout.
14.6 Physical aspects
Demagnetization and wear cause misreads, which the check characters detect. They are an availability issue, not a security issue.
15. Privacy
The stripe carries no personal data. The voucher is a bearer instrument. The service sees terminal, time, amount and payout address. Operators MUST define retention and deletion of these logs under applicable data-protection law.
16. Compatibility
- The backing stamp, claim and transfer follow RFC-001 and Reference Paper §5, §12.3.
- The value rule is the one of Reference Paper §20.9. The stripe voucher is a carrier class of its own and does not depend on any other carrier.
- A card MAY carry a stripe voucher (this RFC) and a chip applet (RFC-003). The two MUST NOT share secrets.
- The voucher MUST NOT be presented to or accepted by payment networks.
17. Testing Requirements
Implementations MUST include tests for:
- Track 1 and Track 3 round trip, wrong sentinel, wrong length, non-zero padding bits, wrong check characters;
- wrong network code, version change;
- double redemption (sequential) and concurrent double redemption (exactly one succeeds);
- idempotent retry with the same
nonce; replay with changed payload; - inactive, expired, revoked and locked vouchers;
- PIN: correct, wrong, third failure locks, unlock;
- register dump without
kcannot redeem; - terminal counter regression, unregistered and revoked terminal;
- payout retry after a service restart without a second payout;
- face value above
v_Mrejected at issuance; - fuzzing of the track parser.
18. Reference Pseudocode
def redeem(req, svc):
verify_terminal(req, svc) # signature, registered, counter
k = req.k
C = H(enc(DOM_CL, k, svc.issuer_id))
with svc.db.transaction():
prev = svc.requests.get(req.request_id)
if prev is not None:
return prev.result if prev.payload == req.payload else E_REQUEST_REPLAY
v = svc.register.get(C)
if v is None: return E_VOUCHER_UNKNOWN
if v.state == "REDEEMED": svc.flag_clone(C, req); return E_VOUCHER_CONSUMED
if v.state != "ACTIVE": return state_error(v.state)
if v.valid_until < svc.chain_height: return E_VOUCHER_EXPIRED
if v.pin_tag is not None: check_pin(v, req) # may lock the voucher
v.state = "REDEEMED"
svc.queue_payout(v.stamp_id, req.payout_address, v.face_value)
svc.requests.put(req.request_id, req.payload, OK)
return OK19. Open Decisions
- The format code for the track 1 record (an issuer code, not the bank card code) and its confirmation against the deployed track standard.
- Whether track 1 or track 3 is the default carrier.
- Partial redemption and change vouchers.
- PIN entry device, key management and the PIN-block format for voucher PINs.
- Default values for
ε_M, velocity limits and voucher validity. - Whether activation is mandatory.
- Terminal registration and revocation governance.
- Whether register commitments are anchored on-chain for audit.
20. Conclusion
Magnetic stripe vouchers extend LSC to the cheapest and most common reader hardware. They are safe only within the limits stated here: a bounded face value, a single online redemption, a register that stores commitments and detection of every second attempt. They complement NFC tokens (RFC-001) and chip cards (RFC-003) for cases where only a stripe reader is available.