1 module tagion.crypto.SecureInterfaceNet;
2 
3 import std.typecons : TypedefType;
4 import tagion.basic.ConsensusExceptions : Check, ConsensusFailCode, SecurityConsensusException;
5 import tagion.basic.Types : Buffer, isBufferType;
6 import tagion.crypto.Types : Fingerprint, Pubkey, Signature;
7 import tagion.hibon.Document : Document;
8 import tagion.hibon.HiBONRecord : HiBONPrefix, isHiBONRecord;
9 
10 alias check = Check!SecurityConsensusException;
11 
12 @safe
13 interface HashNet {
14     uint hashSize() const pure nothrow scope;
15 
16     Fingerprint calcHash(B)(scope const(B) data) const
17     if (isBufferType!B) {
18         return Fingerprint(rawCalcHash(cast(TypedefType!B) data));
19     }
20 
21     immutable(Buffer) rawCalcHash(scope const(ubyte[]) data) const scope;
22     immutable(Buffer) HMAC(scope const(ubyte[]) data) const pure;
23     Fingerprint calcHash(const(Document) doc) const;
24 
25     Fingerprint calcHash(T)(T value) const if (isHiBONRecord!T) {
26         return calcHash(value.toDoc);
27     }
28 
29     string multihash() const pure nothrow;
30 }
31 
32 @safe
33 interface SecureNet : HashNet {
34     import std.typecons : Tuple;
35     alias Signed = Tuple!(Signature, "signature", Fingerprint, "message");
36     @nogc Pubkey pubkey() pure const nothrow;
37     bool verify(const Fingerprint message, const Signature signature, const Pubkey pubkey) const;
38     final bool verify(const Document doc, const Signature signature, const Pubkey pubkey) const {
39 
40         
41 
42             .check(doc.keys.front[0]!is HiBONPrefix.HASH, ConsensusFailCode
43             .SECURITY_MESSAGE_HASH_KEY);
44         immutable message = calcHash(doc);
45         return verify(message, signature, pubkey);
46     }
47 
48     bool verify(T)(T pack, const Signature signature, const Pubkey pubkey) const
49     if (isHiBONRecord!T) {
50         return verify(pack.toDoc, signature, pubkey);
51     }
52 
53     Signature sign(const Fingerprint message) const;
54 
55     final Signed sign(const Document doc) const {
56         const fingerprint = calcHash(doc);
57         return Signed(sign(fingerprint), fingerprint);
58     }
59 
60     Signed sign(T)(T pack) const if (isHiBONRecord!T) {
61         return sign(pack.toDoc);
62     }
63 
64     void createKeyPair(ref ubyte[] privkey);
65     void generateKeyPair(
66             scope const(char[]) passphrase,
67     scope const(char[]) salt = null,
68     void delegate(scope const(ubyte[]) data) @safe dg = null);
69     void eraseKey() pure nothrow;
70 
71     immutable(ubyte[]) ECDHSecret(
72             scope const(ubyte[]) seckey,
73     scope const(Pubkey) pubkey) const;
74 
75     immutable(ubyte[]) ECDHSecret(scope const(Pubkey) pubkey) const;
76 
77     Pubkey getPubkey(scope const(ubyte[]) seckey) const;
78 
79     void derive(string tweak_word, shared(SecureNet) secure_net);
80     void derive(const(ubyte[]) tweak_code, shared(SecureNet) secure_net);
81     void derive(string tweak_word, ref ubyte[] tweak_privkey);
82     void derive(const(ubyte[]) tweak_code, ref ubyte[] tweak_privkey);
83     const(SecureNet) derive(const(ubyte[]) tweak_code) const;
84     const(SecureNet) derive(B)(const B tweak_code) const if (isBufferType!B) {
85         return derive(cast(TypedefType!B) tweak_code);
86     }
87 
88     Pubkey derivePubkey(const(ubyte[]) tweak_code);
89     Pubkey derivePubkey(string tweak_word);
90 
91     SecureNet clone() const;
92 }