Expand description
A text-based data format for cryptographic network protocols.
use nettext::enc::*;
use nettext::dec::*;
use nettext::crypto::*;
let final_payload = {
let keypair = gen_signing_keypair();
// Encode a fist object that represents a payload that will be hashed and signed
let signed_payload = seq([
string("CALL").unwrap(),
string("myfunction").unwrap(),
dict([
("a", string("hello").unwrap()),
("b", string("world").unwrap()),
("c", raw(b"{ a = 12; b = 42 }").unwrap()),
("d", bytes_split(&((0..128u8).collect::<Vec<_>>()))),
]).unwrap(),
keypair.public_key().term().unwrap(),
]).unwrap().encode();
eprintln!("{}", std::str::from_utf8(&signed_payload).unwrap());
let hash = compute_hash(&signed_payload, None);
let sign = compute_signature(&signed_payload[..], &keypair);
// Encode a second object that represents the signed and hashed payload
dict([
("hash", hash.term().unwrap()),
("signature", sign.term().unwrap()),
("payload", raw(&signed_payload).unwrap()),
]).unwrap().encode()
};
eprintln!("{}", std::str::from_utf8(&final_payload).unwrap());
// Decode and check everything is fine
let signed_object = decode(&final_payload).unwrap();
let [hash, signature, payload] = signed_object.dict_of(["hash", "signature", "payload"], false).unwrap();
let hash = hash.hash().unwrap();
let signature = signature.signature().unwrap();
let expected_hash = compute_hash(payload.raw(), None);
assert_eq!(hash, expected_hash);
let object2 = decode(payload.raw()).unwrap();
let [verb, arg1, arg2, pubkey] = object2.seq_of().unwrap();
let pubkey = pubkey.public_key().unwrap();
assert!(verify_signature(&signature, payload.raw(), &pubkey));
assert_eq!(verb.string().unwrap(), "CALL");
assert_eq!(arg1.string().unwrap(), "myfunction");
The value of signed_payload
would be as follows:
CALL myfunction {
a = hello;
b = world;
c = { a = 12; b = 42 };
d = AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v
MDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f
YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8;
} pk.ed25519:inYgWFyL_BzZTsXNKp71r2aVct_3Izi_bkerbzOiz94
And the value of final_payload
would be as follows:
{
hash = h.b2:B1AnRocS90DmqxynGyvvBNuh-brucNO7-5hrsGplJr0;
payload = CALL myfunction {
a = hello;
b = world;
c = { a = 12; b = 42 };
d = AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v
MDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f
YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8;
} pk.ed25519:inYgWFyL_BzZTsXNKp71r2aVct_3Izi_bkerbzOiz94;
signature = sig.ed25519:LvLC1gHxNxUH44HHQRO-zWtLM4WyXhiYLFr94qTdI311Wa-kmgZsaWqSWe3jcjkS4PnsWSNt5apgbhR68cWWCg;
}
Note that the value of text1
is embedded as-is inside text2
. This is what allows us
to check the hash and the signature: the raw representation of the term hasn’t changed.