bitcoin_crypter/
crypter.rs

1/*! 
2  | Private key encryption is done based on
3  | a CMasterKey, which holds a salt and random
4  | encryption key.
5  |
6  | CMasterKeys are encrypted using AES-256-CBC
7  | using a key derived using derivation method
8  | nDerivationMethod (0 == EVP_sha512()) and
9  | derivation iterations nDeriveIterations.
10  | vchOtherDerivationParameters is provided for
11  | alternative algorithms which may require more
12  | parameters (such as scrypt).
13  |
14  | Wallet Private Keys are then encrypted using
15  | AES-256-CBC with the double-sha256 of the
16  | public key as the IV, and the master key's key
17  | as the encryption key (see keystore.[ch]).
18  */
19
20crate::ix!();
21
22//-------------------------------------------[.cpp/bitcoin/src/wallet/crypter.h]
23//-------------------------------------------[.cpp/bitcoin/src/wallet/crypter.cpp]
24
25pub const WALLET_CRYPTO_KEY_SIZE:  u32 = 32;
26pub const WALLET_CRYPTO_SALT_SIZE: u32 = 8;
27pub const WALLET_CRYPTO_IV_SIZE:   u32 = 16;
28
29pub type KeyingMaterial = Vec<u8,SecureAllocator>;
30
31/**
32  | Encryption/decryption context with
33  | key information
34  |
35  */
36pub struct Crypter {
37    vch_key: Vec<u8,SecureAllocator>,
38    vchiv:   Vec<u8,SecureAllocator>,
39    key_set: bool,
40}
41
42impl Default for Crypter {
43    
44    fn default() -> Self {
45        todo!();
46        /*
47
48
49            fKeySet = false;
50            vchKey.resize(WALLET_CRYPTO_KEY_SIZE);
51            vchIV.resize(WALLET_CRYPTO_IV_SIZE);
52        */
53    }
54}
55
56impl Drop for Crypter {
57    fn drop(&mut self) {
58        todo!();
59        /*
60            CleanKey();
61        */
62    }
63}
64
65impl Crypter {
66    
67    pub fn clean_key(&mut self)  {
68        
69        todo!();
70        /*
71            memory_cleanse(vchKey.data(), vchKey.size());
72            memory_cleanse(vchIV.data(), vchIV.size());
73            fKeySet = false;
74        */
75    }
76    
77    pub fn bytes_to_keysha512aes(&self, 
78        ch_salt:      &Vec<u8>,
79        str_key_data: &SecureString,
80        count:        i32,
81        key:          *mut u8,
82        iv:           *mut u8) -> i32 {
83        
84        todo!();
85        /*
86            // This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc
87        // cipher and sha512 message digest. Because sha512's output size (64b) is
88        // greater than the aes256 block size (16b) + aes256 key size (32b),
89        // there's no need to process more than once (D_0).
90
91        if(!count || !key || !iv)
92            return 0;
93
94        unsigned char buf[CSHA512::OUTPUT_SIZE];
95        CSHA512 di;
96
97        di.Write((const unsigned char*)strKeyData.data(), strKeyData.size());
98        di.Write(chSalt.data(), chSalt.size());
99        di.Finalize(buf);
100
101        for(int i = 0; i != count - 1; i++)
102            di.Reset().Write(buf, sizeof(buf)).Finalize(buf);
103
104        memcpy(key, buf, WALLET_CRYPTO_KEY_SIZE);
105        memcpy(iv, buf + WALLET_CRYPTO_KEY_SIZE, WALLET_CRYPTO_IV_SIZE);
106        memory_cleanse(buf, sizeof(buf));
107        return WALLET_CRYPTO_KEY_SIZE;
108        */
109    }
110    
111    pub fn set_key_from_passphrase(&mut self, 
112        str_key_data:        &SecureString,
113        ch_salt:             &Vec<u8>,
114        n_rounds:            u32,
115        n_derivation_method: u32) -> bool {
116        
117        todo!();
118        /*
119            if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
120            return false;
121
122        int i = 0;
123        if (nDerivationMethod == 0)
124            i = BytesToKeySHA512AES(chSalt, strKeyData, nRounds, vchKey.data(), vchIV.data());
125
126        if (i != (int)WALLET_CRYPTO_KEY_SIZE)
127        {
128            memory_cleanse(vchKey.data(), vchKey.size());
129            memory_cleanse(vchIV.data(), vchIV.size());
130            return false;
131        }
132
133        fKeySet = true;
134        return true;
135        */
136    }
137    
138    pub fn set_key(&mut self, 
139        ch_new_key: &KeyingMaterial,
140        ch_newiv:   &Vec<u8>) -> bool {
141        
142        todo!();
143        /*
144            if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_IV_SIZE)
145            return false;
146
147        memcpy(vchKey.data(), chNewKey.data(), chNewKey.size());
148        memcpy(vchIV.data(), chNewIV.data(), chNewIV.size());
149
150        fKeySet = true;
151        return true;
152        */
153    }
154    
155    pub fn encrypt(&self, 
156        vch_plaintext:  &KeyingMaterial,
157        vch_ciphertext: &mut Vec<u8>) -> bool {
158        
159        todo!();
160        /*
161            if (!fKeySet)
162            return false;
163
164        // max ciphertext len for a n bytes of plaintext is
165        // n + AES_BLOCKSIZE bytes
166        vchCiphertext.resize(vchPlaintext.size() + AES_BLOCKSIZE);
167
168        AES256CBCEncrypt enc(vchKey.data(), vchIV.data(), true);
169        size_t nLen = enc.Encrypt(vchPlaintext.data(), vchPlaintext.size(), vchCiphertext.data());
170        if(nLen < vchPlaintext.size())
171            return false;
172        vchCiphertext.resize(nLen);
173
174        return true;
175        */
176    }
177    
178    pub fn decrypt(&self, 
179        vch_ciphertext: &Vec<u8>,
180        vch_plaintext:  &mut KeyingMaterial) -> bool {
181        
182        todo!();
183        /*
184            if (!fKeySet)
185            return false;
186
187        // plaintext will always be equal to or lesser than length of ciphertext
188        int nLen = vchCiphertext.size();
189
190        vchPlaintext.resize(nLen);
191
192        AES256CBCDecrypt dec(vchKey.data(), vchIV.data(), true);
193        nLen = dec.Decrypt(vchCiphertext.data(), vchCiphertext.size(), vchPlaintext.data());
194        if(nLen == 0)
195            return false;
196        vchPlaintext.resize(nLen);
197        return true;
198        */
199    }
200}
201
202pub fn encrypt_secret(
203        master_key:     &KeyingMaterial,
204        vch_plaintext:  &KeyingMaterial,
205        niv:            &u256,
206        vch_ciphertext: &mut Vec<u8>) -> bool {
207    
208    todo!();
209        /*
210            CCrypter cKeyCrypter;
211        std::vector<unsigned char> chIV(WALLET_CRYPTO_IV_SIZE);
212        memcpy(chIV.data(), &nIV, WALLET_CRYPTO_IV_SIZE);
213        if(!cKeyCrypter.SetKey(vMasterKey, chIV))
214            return false;
215        return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext);
216        */
217}
218
219pub fn decrypt_secret(
220        master_key:     &KeyingMaterial,
221        vch_ciphertext: &Vec<u8>,
222        niv:            &u256,
223        vch_plaintext:  &mut KeyingMaterial) -> bool {
224    
225    todo!();
226        /*
227            CCrypter cKeyCrypter;
228        std::vector<unsigned char> chIV(WALLET_CRYPTO_IV_SIZE);
229        memcpy(chIV.data(), &nIV, WALLET_CRYPTO_IV_SIZE);
230        if(!cKeyCrypter.SetKey(vMasterKey, chIV))
231            return false;
232        return cKeyCrypter.Decrypt(vchCiphertext, vchPlaintext);
233        */
234}
235
236pub fn decrypt_key(
237        master_key:         &KeyingMaterial,
238        vch_crypted_secret: &Vec<u8>,
239        vch_pub_key:        &PubKey,
240        key:                &mut Key) -> bool {
241    
242    todo!();
243        /*
244            CKeyingMaterial vchSecret;
245        if(!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
246            return false;
247
248        if (vchSecret.size() != 32)
249            return false;
250
251        key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
252        return key.VerifyPubKey(vchPubKey);
253        */
254}