spike(block2): de-risk social layer — key derivation, OfferTransport, NIP-99 round-trip
Throwaway research spike (spike/ branch, outside pub workspace, no prod deps touched). Validates the open Block 2 decisions before committing a funded round: 1. Deterministic one-way secp256k1 (Nostr) key derived from the Ğ1 root seed via HKDF — user still backs up ONE thing. Reproducible + signs (BIP340). 2. OfferTransport abstraction over Nostr NIP-99 (kind 30402); Offer stays inventory/location-agnostic, geohash coarsened on the wire (tested). 3. publish->discover-by-geohash proven end-to-end against an in-process hermetic mini-relay (~34ms round-trip). Findings + risks + recommendation in docs/design/spike-block2-findings.md. Block 1 suite untouched. 14 tests green, analyzer clean.
This commit is contained in:
parent
6eb1517ffb
commit
49b872b405
16 changed files with 1284 additions and 0 deletions
32
spike/block2_spike/lib/src/hkdf.dart
Normal file
32
spike/block2_spike/lib/src/hkdf.dart
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import 'dart:typed_data';
|
||||
|
||||
import 'package:crypto/crypto.dart';
|
||||
|
||||
/// Minimal, self-contained HKDF-SHA256 (RFC 5869), synchronous.
|
||||
///
|
||||
/// Spike-local so the derivation stays pure Dart and easy to reason about. In
|
||||
/// production this would reuse `commons_core`'s `Hkdf` (the `cryptography`
|
||||
/// package already ships one — see backup_box.dart), keyed by a domain string.
|
||||
Uint8List hkdfSha256({
|
||||
required List<int> ikm,
|
||||
required String info,
|
||||
List<int> salt = const [],
|
||||
int length = 32,
|
||||
}) {
|
||||
// Extract.
|
||||
final actualSalt = salt.isEmpty ? Uint8List(32) : salt; // HashLen zeros
|
||||
final prk = Hmac(sha256, actualSalt).convert(ikm).bytes;
|
||||
|
||||
// Expand.
|
||||
final infoBytes = info.codeUnits;
|
||||
final out = <int>[];
|
||||
var previous = <int>[];
|
||||
var counter = 1;
|
||||
while (out.length < length) {
|
||||
final input = <int>[...previous, ...infoBytes, counter];
|
||||
previous = Hmac(sha256, prk).convert(input).bytes;
|
||||
out.addAll(previous);
|
||||
counter++;
|
||||
}
|
||||
return Uint8List.fromList(out.sublist(0, length));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue