mirror of
https://github.com/logos-storage/logos-storage-docs-obsidian.git
synced 2026-01-08 08:13:12 +00:00
updates encryption docs
This commit is contained in:
parent
806d410b1f
commit
2c06131396
58
10 Notes/BearSSL hashing.md
Normal file
58
10 Notes/BearSSL hashing.md
Normal file
@ -0,0 +1,58 @@
|
||||
Here is an example, of how to use hashing in [[BearSSL]]:
|
||||
|
||||
```nim
|
||||
import bearssl/hash
|
||||
import stew/byteutils
|
||||
|
||||
let data = "0123456789abcdef".toBytes
|
||||
let buff = newSeq[byte](sha256SIZE)
|
||||
|
||||
var sha256HashCtx = Sha256Context()
|
||||
sha256Init(sha256HashCtx)
|
||||
sha224Update(sha256HashCtx, addr data[0], data.len.uint)
|
||||
sha256Out(sha256HashCtx, addr buff[0])
|
||||
|
||||
echo "Hash out: ", buff.toHex
|
||||
|
||||
```
|
||||
|
||||
>[!note]
|
||||
> notice that above we use `sha224Update` and not the expected `sha256update`. This is because of a bug, which is addressed here: https://github.com/status-im/nim-bearssl/pull/68
|
||||
|
||||
BearSSL also simulates an [OOP interface](https://bearssl.org/oop.html), which can be used to create a generic `hash` function which can then be reused for various hashing algorithms:
|
||||
|
||||
```nim
|
||||
import bearssl/hash
|
||||
|
||||
proc hash(hashClass: ptr HashClass, data: openArray[byte]): seq[byte] =
|
||||
var compatCtx = HashCompatContext()
|
||||
let buffSize = (hashClass[].desc shr HASHDESC_OUT_OFF) and HASHDESC_OUT_MASK
|
||||
result = newSeq[byte](buffSize)
|
||||
|
||||
let hashClassPtrPtr: ConstPtrPtrHashClass = addr(compatCtx.vtable)
|
||||
|
||||
hashClass[].init(hashClassPtrPtr)
|
||||
hashClass[].update(hashClassPtrPtr, addr data[0], data.len.uint)
|
||||
hashClass[].`out`(hashClassPtrPtr, addr result[0])
|
||||
```
|
||||
|
||||
Then such a hash function can be conveniently reused for various hashing functions:
|
||||
|
||||
```nim
|
||||
import stew/byteutils
|
||||
|
||||
let data = "0123456789abcdef".toBytes
|
||||
|
||||
var sha256HashCtx = Sha256Context()
|
||||
sha256Init(sha256HashCtx)
|
||||
echo "Hash out[sha256]: ", hash(sha256HashCtx.vtable, data).toHex
|
||||
|
||||
var sha1HashCtx = Sha1Context()
|
||||
sha1Init(sha1HashCtx)
|
||||
echo "Hash out[sha1]: ", hash(sha1HashCtx.vtable, data).toHex
|
||||
|
||||
var md5Ctx = Md5Context()
|
||||
md5Init(md5Ctx)
|
||||
echo "Hash out[md5]: ", hash(md5Ctx.vtable, data).toHex
|
||||
```
|
||||
|
||||
@ -20,7 +20,7 @@ I would argue that at the moment we should only do something very basic, that is
|
||||
We need to choose a [stream cipher](https://en.wikipedia.org/wiki/Stream_cipher). Which one to choose doesn't really matter as long as we don't fuck up the many subtle details. Some natural options:
|
||||
|
||||
- something based on the [AES block cipher](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
|
||||
- [Salsa20](https://en.wikipedia.org/wiki/Salsa20) or ChaCha
|
||||
- [Salsa20](https://en.wikipedia.org/wiki/Salsa20) or ChaCha (newer)
|
||||
- just `XOR` with Shake or TurboShake (Shake is the SHA3 XOF)
|
||||
|
||||
AES is usually a default choice because it's a standard, it's well-known (you don't have to explain the choice), and hardware-accelerated. However, there are many details allowing you to shoot yourself in the foot.
|
||||
@ -77,6 +77,8 @@ A common mitigation strategy is to include additional entropy based for example
|
||||
|
||||
## A proposal
|
||||
|
||||
^b2e265
|
||||
|
||||
Based on the above, I have a very simple proposal:
|
||||
|
||||
- use a freshly generated random master key (at least 256 bits) per dataset (generated and kept on the user's machine)
|
||||
|
||||
@ -1,7 +1,27 @@
|
||||
---
|
||||
related-to:
|
||||
- "[[Codex Encryption Basis]]"
|
||||
- "[[How to get a pointer to a seq to pass it to a C library]]"
|
||||
---
|
||||
As summarized in [[Codex Encryption Basis#^b2e265|the proposal]], we:
|
||||
|
||||
- use a freshly generated random master key (at least 256 bits) per dataset (generated and kept on the user's machine)
|
||||
- derive a new encryption key and also an IV for each block from the master key and the block index
|
||||
- use for example AES192-CBC
|
||||
|
||||
For example, we could have
|
||||
|
||||
key = SHA256( MASTER_KEY || block_index ), truncated to 192 bits
|
||||
IV = SHA256( MASTER_IV || block_index ), truncated to 128 bits
|
||||
|
||||
where both `MASTER_KEY` and `MASTER_IV` are 256 bit random numbers, and `||` denotes concatenation.
|
||||
|
||||
If storing 512 bits (as opposed to a 256 bit minimum) of key material is a problem, we could derive both by the same key, for example as
|
||||
|
||||
key' = SHA256( MASTER_KEY || 0x01 || block_index ), truncated to 192 bits
|
||||
IV' = SHA256( MASTER_KEY || 0x02 || block_index ), truncated to 128 bits
|
||||
|
||||
|
||||
Some context info:
|
||||
|
||||
- [bearssl](https://bearssl.org/)
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
Having a Nim sequence:
|
||||
|
||||
```nim
|
||||
var buff = newSeq[byte](buffSize)
|
||||
```
|
||||
|
||||
if you want to get a pointer to the underlying data buffer that is suitable for being passed to a C library, you can simply use:
|
||||
|
||||
```nim
|
||||
sha256Update(ctx, addr buff[0], input[i].len.uint)
|
||||
```
|
||||
|
||||
If your input is a `string`, you can use the following:
|
||||
|
||||
```nim
|
||||
let str = "abcdefghijklmnopqrstuvwxyz"
|
||||
sha256Update(ctx, str.cstring, input[i].len.uint)
|
||||
```
|
||||
|
||||
Here we use `sha256Update` from [[BearSSL]] library. See [[BearSSL hashing]] for more complete examples.
|
||||
See also [Accessing seq pointer](https://forum.nim-lang.org/t/1489) and [Use cstring for C binding](https://forum.nim-lang.org/t/8179) on Nim forum.
|
||||
Loading…
x
Reference in New Issue
Block a user