Single-use-seal primitive represents an efficient enhancement for WoT model of key revocation: it provides independent parties an ability to detect and timestamp key revocation without contacting the owner of the original identity.
RGB-22 standard is created to leverage this advantage and provide an alternative WoT solution to GPG/PGP. It can be combined with Storm protocol, as a better alternative to PGP key servers.
Design
Specification
Interface specification is the following Contractum code:
-- Defined by LNPBP-31 standard in `RGBContract.sty` fileimport urn:ubideco:stl:6vbr9ZrtsD9aBjo5qRQ36QEZPVucqvRRjKCPqE8yPeJr#choice-little-boxer as RGBContractdataXonlyPubkey:: [Byte^32]dataSchnorrSig:: [Byte^64]dataEdKey:: [Byte^32]dataEdSig:: [Byte^64)dataFact:: [Byte+] -- JSON encoded stringdataPubkey:: secp256k1(XonlyPubkey) | curve25519(EdKey)dataSig:: secp256k1(XonlyPubkey,SchnorrSig) | ed25519(EdKey, EdSig)dataAttestation:: facts [Fact+], attestedBy RGB22.ContractId, signature SigdataFullName:: [Unicode^0..0xFF]interface RGB22 global nickName :: RGBContract.Name global fullName ::FullName global emails+::Email global facts*::Attestation global photo*:: (MimeType, [Byte]) global created :: RGBContract.Timestamp owned nameRight owned attestRight owned revokableKey+::Pubkey op Revoke :: revokableKey -> revokableKey? op Rename :: nameRight , nickName , fullName , {emails ^0..0xff} , {photo ^0..0xff}-> nameRight op Attest :: attestRight , {facts ^1..0xFFFF}-> attestRight , {revokableKey}
Compatibility
Rationale
Reference implementation
use Secp256k1, Ed25519import RGB22fn checkKey :: key Pubkey!! invalidKey key: Pubkey.secp256k1(k) -> Secp256k1.checkKey k !! invalidKey Pubkey.curve25519(k) -> Ed25519.checkKey k !! invalidKeyschema BaseIdentity global Name :: [Unicode+] global Emails{+} ::Email global Facts{*} ::Attestation global Photo?:: (MimeType, [Byte]) owned NameRight owned AttestRight owned RevokableKey{+} ::Pubkeygenesis:: name Name, emails {Emails+}, keys {RevokableKey+}!! invalidKey keys => key -> checkKey key op revoke :: old RevokableKey-> new RevokableKey?!! invalidKey| sameKey checkKey new!(old =? new) !! sameKey op rename ::NameRight->NameRight<- Name, {Emails+} op attest ::AttestRight->AttestRight, {RevokableKey}<- atts {Attestation}!! invalidSig atts => a -> a.signature: Sig.secp256k1(key, sig) => Secp256k1.verify key, sig !! invalidSig Sig.ed25519k1(key, sig) => Ed25519.verify key, sig !! invalidSigimplement RGB21 for BaseIdentity
Acknowledgements
References
Test vectors
use BaseIdentity from identity.conlet orig = Seal(fac503c4641c3deda72a2d00bc9d6ff1094b15276c386efea403746a91436772,1)contract meSatoshiNakamoto := BaseIdentity ( name :="Satoshi Nakamoto" emails := {"satoshi@nakam.oto"} keys := [ (orig, Pubkey.secp256k1(0x028730eeeec41802621d177507b086f390ae600ba3ca5e428b13913af4c2cd25b3)) ])transition iLostMyKey := BaseIdentity.revoke ( old := orig, new := (Seal(~:1), Pubkey.curve25519(0x0219db0a4e0eb8cb833608c08d76b9b279ec44a851ab82cc6fd68a9b32624bfa8b)))
$ rgb-cli exec satoshi.conRegistering schema ... successIssuing contract meSatoshiNakamoto ... successPreparing transition iLostMyKey ... saved to `iLostMyKey.rgb` and `iLostMyKey.psbt`