@@ -6,32 +6,31 @@ use multicodec::Codec;
66use multikey:: { nonce, Multikey , Nonce , Views } ;
77use multisig:: Multisig ;
88use multitrait:: { Null , TryDecodeFrom } ;
9- use multiutil:: { BaseEncoded , CodecInfo , EncodingInfo } ;
9+ use multiutil:: { BaseEncoded , CodecInfo , DetectedEncoder , EncodingInfo } ;
1010
1111/// the Vlad multicodec sigil
1212pub const SIGIL : Codec = Codec :: Vlad ;
1313
14- /// a multibase encoded Vlad
15- pub type EncodedVlad = BaseEncoded < Vlad > ;
14+ /// a multibase encoded Vlad that can decode from any number of encoding but always encodes to
15+ /// Vlad's preferred Base32Lower multibase encoding (i.e. liberal in what we except, strict in what
16+ /// we generate)
17+ pub type EncodedVlad = BaseEncoded < Vlad , DetectedEncoder > ;
1618
17- /// A verifiable long-lived address (VLAD) represents an identifier for loosely
18- /// coupled distributed systems that combines a random unique idenitfier (none)
19- /// with the content address of a verification function in executable format.
19+ /// A verifiable long-lived address (VLAD) represents an identifier for loosely coupled distributed
20+ /// systems that combines a random unique idenitfier (none) with the content address of a
21+ /// verification function in executable format.
2022///
21- /// The goal is to avoid the anti-pattern of using public keys as identifiers.
22- /// Public keys are chosen because they are random and unique enough to be
23- /// useful identifiers and are also a cryptographic commitment to a validation
24- /// function--the public key signature validation function. Using public keys
25- /// as an identifer is an anti-pattern because using key material means that
26- /// the identifiers are subject to compromise and must be rotated often to
27- /// maintain security so their "shelf-life" is limited. Rotating and/or
28- /// abandoning keys due to compromise causes the identifier to become invalid.
29- /// Any system that stores these identifiers then possesses broken links to
30- /// the value the identifier is associated with.
23+ /// The goal is to avoid the anti-pattern of using public keys as identifiers. Public keys are
24+ /// chosen because they are random and unique enough to be useful identifiers and are also a
25+ /// cryptographic commitment to a validation function--the public key signature validation
26+ /// function. Using public keys as an identifer is an anti-pattern because using key material means
27+ /// that the identifiers are subject to compromise and must be rotated often to maintain security
28+ /// so their "shelf-life" is limited. Rotating and/or abandoning keys due to compromise causes the
29+ /// identifier to become invalid. Any system that stores these identifiers then possesses broken
30+ /// links to the value the identifier is associated with.
3131///
32- /// The solution is to realize that we only need a random identifier and a
33- /// cryptographic commitment to a validation function to replace keys as
34- /// identifiers. VLADs meet those requirements.
32+ /// The solution is to realize that we only need a random identifier and a cryptographic commitment
33+ /// to a validation function to replace keys as identifiers. VLADs meet those requirements.
3534#[ derive( Clone , Default , Eq , Ord , PartialEq , PartialOrd ) ]
3635pub struct Vlad {
3736 /// the random nonce for uniqueness
@@ -203,6 +202,7 @@ mod tests {
203202 use crate :: cid;
204203 use multihash:: mh;
205204 use multikey:: EncodedMultikey ;
205+ use multiutil:: base_name;
206206
207207 #[ test]
208208 fn test_default ( ) {
@@ -295,6 +295,59 @@ mod tests {
295295 assert_eq ! ( vlad, EncodedVlad :: try_from( s. as_str( ) ) . unwrap( ) ) ;
296296 }
297297
298+ #[ test]
299+ fn test_encodings_roundtrip ( ) {
300+ // build a nonce
301+ let mut rng = rand:: rngs:: OsRng :: default ( ) ;
302+ let nonce = nonce:: Builder :: new_from_random_bytes ( 32 , & mut rng)
303+ . try_build ( )
304+ . unwrap ( ) ;
305+
306+ // build a cid
307+ let cid = cid:: Builder :: new ( Codec :: Cidv1 )
308+ . with_target_codec ( Codec :: DagCbor )
309+ . with_hash (
310+ & mh:: Builder :: new_from_bytes ( Codec :: Sha3512 , b"for great justice, move every zig!" )
311+ . unwrap ( )
312+ . try_build ( )
313+ . unwrap ( ) ,
314+ )
315+ . try_build ( )
316+ . unwrap ( ) ;
317+
318+ let encodings = vec ! [
319+ Base :: Base2 ,
320+ Base :: Base8 ,
321+ Base :: Base10 ,
322+ Base :: Base16Lower ,
323+ Base :: Base16Upper ,
324+ Base :: Base32Lower ,
325+ Base :: Base32Upper ,
326+ Base :: Base32HexLower ,
327+ Base :: Base32HexUpper ,
328+ Base :: Base32Z ,
329+ Base :: Base36Lower ,
330+ Base :: Base36Upper ,
331+ Base :: Base58Flickr ,
332+ Base :: Base58Btc ,
333+ Base :: Base64 ,
334+ Base :: Base64Url ,
335+ ] ;
336+
337+ for encoding in encodings {
338+ let vlad = Builder :: default ( )
339+ . with_nonce ( & nonce)
340+ . with_cid ( & cid)
341+ . with_base_encoding ( encoding)
342+ . try_build_encoded ( )
343+ . unwrap ( ) ;
344+
345+ let s = vlad. to_string ( ) ;
346+ println ! ( "{}: ({}) {}" , base_name( encoding) , s. len( ) , s) ;
347+ assert_eq ! ( vlad, EncodedVlad :: try_from( s. as_str( ) ) . unwrap( ) ) ;
348+ }
349+ }
350+
298351 #[ test]
299352 fn test_signed_vlad ( ) {
300353 // build a cid
@@ -309,24 +362,26 @@ mod tests {
309362 . try_build ( )
310363 . unwrap ( ) ;
311364
312- let s = "zF3WX3Dwnv7jv2nPfYL6e2XaLdNyaiwkPyzEtgw65d872KYG22jezzuYPtrds8WSJ3Sv8SCA " ;
365+ let s = "bhkasmcdumvzxiidlmv4qcaja42hlepmnedftr7ibzzo56qaswo6jvdmypljivo3b3imhjxqfnsvq " ;
313366 let mk = EncodedMultikey :: try_from ( s) . unwrap ( ) ;
314367
315368 let vlad = Builder :: default ( )
316369 . with_signing_key ( & mk)
317370 . with_cid ( & cid)
318- . with_base_encoding ( Base :: Base16Lower )
371+ . with_base_encoding ( Base :: Base32Z )
319372 . try_build_encoded ( )
320373 . unwrap ( ) ;
321374
322375 // make sure the signature checks out
323376 assert_eq ! ( ( ) , vlad. verify( & mk) . unwrap( ) ) ;
324377 let s = vlad. to_string ( ) ;
325- println ! ( "({}) {}" , s. len( ) , s) ;
326- assert_eq ! ( vlad, EncodedVlad :: try_from( s. as_str( ) ) . unwrap( ) ) ;
378+ //println!("BASE32Z ({}) {}", s.len(), s);
379+ let de = EncodedVlad :: try_from ( s. as_str ( ) ) . unwrap ( ) ;
380+ assert_eq ! ( vlad, de) ;
381+ assert_eq ! ( Base :: Base32Z , de. encoding( ) ) ;
327382 let vlad = vlad. to_inner ( ) ;
328383 let v: Vec < u8 > = vlad. clone ( ) . into ( ) ;
329- println ! ( "BLAH: {}" , hex:: encode( & v) ) ;
384+ // println!("BLAH: {}", hex::encode(&v));
330385 assert_eq ! ( vlad, Vlad :: try_from( v. as_ref( ) ) . unwrap( ) ) ;
331386 }
332387
0 commit comments