init: v1.0.0

This commit is contained in:
yaole
2026-05-27 23:03:00 +08:00
commit 8d97f750eb
466 changed files with 80067 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
//go:build ignore
// +build ignore
package paillier
// envelope provide hybrid encryption for a user with a remote cryptographic server.
// The server has a KEK and the user wants to encrypt a file.
// 1. The user generate a random user key ukey
// 2. The user use ukey to encrypt the file
// 3. The user do the followings to encrypt the ukey with KEK without leaking ukey to the server:
// 3-0. The user generate a (temporary or long term) paillier key pair (sk, pk).
// 3-1. The user encrypt ukey with paillier encryption: ukeyCipher = PaiEnc(ukey, pk)
// 3-2. The server HOMOMORPHICLY encrypt ukey with KEK: ukeyEnvelopeCipher = PaiEnc(SM4Enc(ukey, KEK), pk)
// 3-3. The user decrypt ukeyEnvelopeCipher and get ukeyEnvelope = SM4Enc(ukey, KEK)
//
// The user do the following to decrypt the ukey and then to decrypt the file.
// Also without leaking ukey.
// 1. The user generate a (temporary or long term) paillier key pair (sk, pk).
// 2. User encrypt ukeyEnvelope: ukeyEnvelopeCipher = PaiEnc(ukeyEnvelope, pk)
// 3. The server HOMORPHICLY decrypt ukeyEnvelopeCipher: ukeyCipher = PaiEnc(ukey, pk)
// 4. The user decrypt ukeyCipher, with ukey.
import (
"fmt"
"math/big"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/sm/sm4"
)
// xyzw => 0x0y0z0w
var tbl = []byte{0, 1, 4, 5, 16, 17, 20, 21, 64, 65, 68, 69, 80, 81, 84, 85}
type EnvelopeUser struct{}
type EnvelopeServer struct{}
// EncryptUserKey
func (EnvelopeUser) EncryptUserKey(ukey []byte, pk *PublicKey) (ukeyCipher *Cipher, err error) {
if len(ukey)*8*2 > pk.Bits() {
return nil, fmt.Errorf("input key too long, should less than %d bytes", pk.Bits()/8/2)
}
buf := make([]byte, 0, len(ukey)*2)
for _, k := range ukey {
buf = append(buf, tbl[k&0xf])
buf = append(buf, tbl[k>>4])
}
return pk.Encrypt(new(big.Int).SetBytes(buf), grand.Reader)
}
func DecryptKey(c *Cipher, keyLength int, priKey *PrivateKey) ([]byte, error) {
k, err := priKey.Decrypt(c)
_ = err
key2 := make([]byte, keyLength*2)
k.FillBytes(key2)
key := make([]byte, keyLength)
for i := 0; i < len(key); i++ {
x := key2[2*i]
y := key2[2*i+1]
n := byte(0)
n |= (x >> 0) & 1
n |= (x >> 1) & 2
n |= (x >> 2) & 4
n |= (x >> 3) & 8
key[i] = n
n = byte(0)
n |= (y >> 0) & 1
n |= (y >> 1) & 2
n |= (y >> 2) & 4
n |= (y >> 3) & 8
key[i] |= (n << 4)
}
return key, nil
}
func GenEnvelope(c0 *Cipher, kek []byte, pubkey *PublicKey) ([]byte, *Cipher, error) {
iv := grand.GetRandom(16)
c1, err := sm4.EncryptECB(nil, kek, iv) // c1 = sm4.Enc(iv)
c2, err := EncryptUserKey(c1, pubkey) // c2 = PaiEnc(sm4.Enc(iv))
c2.HomomorphicAdd(c2, c0, pubkey) // c2 = PaiEnc(sm4.Enc(iv) ^ key)
_ = err
return iv, c2, nil
}
func DecryptEnvelope(c *Cipher, prikey *PrivateKey) ([]byte, error) {
k, err := prikey.Decrypt(c)
_ = err
key2 := make([]byte, 32)
k.FillBytes(key2)
key := make([]byte, 16)
for i := 0; i < 16; i++ {
x := key2[2*i]
y := key2[2*i+1]
n := byte(0)
n |= (x >> 0) & 1
n |= (x >> 1) & 2
n |= (x >> 2) & 4
n |= (x >> 3) & 8
key[i] = n
n = byte(0)
n |= (y >> 0) & 1
n |= (y >> 1) & 2
n |= (y >> 2) & 4
n |= (y >> 3) & 8
key[i] |= (n << 4)
}
return key, nil
}