mirror of
https://github.com/taigrr/arc
synced 2025-01-18 04:33:13 -08:00
91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
|
|
|
package ecies
|
|
|
|
import (
|
|
"crypto/subtle"
|
|
"errors"
|
|
|
|
"github.com/dchest/blake2b"
|
|
"github.com/wg/ecies/xchacha20poly1305"
|
|
)
|
|
|
|
var (
|
|
ErrBoxAuthFailed = errors.New("box: message auth failed")
|
|
ErrBoxTooSmall = errors.New("box: destination too small")
|
|
ErrBoxInvariant = errors.New("box: invariant violation")
|
|
)
|
|
|
|
type Box struct {
|
|
key [xchacha20poly1305.KeySize]byte
|
|
xchacha20poly1305.XChaCha20Poly1305
|
|
}
|
|
|
|
func NewX25519XChaCha20Poly1305(publicKey, privateKey *[32]byte) (*Box, error) {
|
|
var secret [32]byte
|
|
if err := X25519(&secret, publicKey, privateKey); err != nil {
|
|
return nil, err
|
|
}
|
|
return newXChaCha20Poly1305Box(secret[:])
|
|
}
|
|
|
|
func NewX448XChaCha20Poly1305(publicKey, privateKey *[56]byte) (*Box, error) {
|
|
var secret [56]byte
|
|
if err := X448(&secret, publicKey, privateKey); err != nil {
|
|
return nil, err
|
|
}
|
|
return newXChaCha20Poly1305Box(secret[:])
|
|
}
|
|
|
|
func (b *Box) Seal(dst, msg, nonce []byte) error {
|
|
if cap(dst) < len(msg)+xchacha20poly1305.TagSize {
|
|
return ErrBoxTooSmall
|
|
}
|
|
|
|
if err := b.Init(b.key[:], nonce); err != nil {
|
|
return err
|
|
}
|
|
|
|
n := len(msg)
|
|
b.Encrypt(dst, msg)
|
|
b.Tag(dst[n:n])
|
|
|
|
return nil
|
|
}
|
|
|
|
func (b *Box) Open(dst, msg, nonce []byte) error {
|
|
if cap(dst) < len(msg)-xchacha20poly1305.TagSize {
|
|
return ErrBoxTooSmall
|
|
}
|
|
|
|
if err := b.Init(b.key[:], nonce); err != nil {
|
|
return err
|
|
}
|
|
|
|
n := len(msg) - xchacha20poly1305.TagSize
|
|
msg, tag := msg[:n], msg[n:]
|
|
b.Decrypt(dst, msg)
|
|
|
|
if subtle.ConstantTimeCompare(tag, b.Tag(nil)) != 1 {
|
|
return ErrBoxAuthFailed
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func newXChaCha20Poly1305Box(secret []byte) (*Box, error) {
|
|
h, err := blake2b.New(&blake2b.Config{
|
|
Size: xchacha20poly1305.KeySize,
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, ErrBoxInvariant
|
|
}
|
|
|
|
box := &Box{}
|
|
h.Write(secret)
|
|
h.Sum(box.key[:0])
|
|
|
|
return box, nil
|
|
}
|