Michal Iskierko 6d31343205 feat: Waku v2 bridge
Issue #12610
2024-02-22 17:07:59 +01:00

251 lines
6.2 KiB
Go

package rln
/*
#include "./librln.h"
*/
import "C"
import (
"errors"
"unsafe"
)
// RLN represents the context used for rln.
type RLN struct {
ptr *C.RLN
}
func toCBufferPtr(input []byte) *C.Buffer {
buf := toBuffer(input)
size := int(unsafe.Sizeof(buf))
in := (*C.Buffer)(C.malloc(C.size_t(size)))
*in = buf
return in
}
// toBuffer converts the input to a buffer object that is used to communicate data with the rln lib
func toBuffer(data []byte) C.Buffer {
dataPtr, dataLen := sliceToPtr(data)
return C.Buffer{
ptr: dataPtr,
len: C.uintptr_t(dataLen),
}
}
func sliceToPtr(slice []byte) (*C.uchar, C.int) {
if len(slice) == 0 {
return nil, 0
} else {
return (*C.uchar)(unsafe.Pointer(&slice[0])), C.int(len(slice))
}
}
func NewWithParams(depth int, wasm []byte, zkey []byte, verifKey []byte, treeConfig []byte) (*RLN, error) {
wasmBuffer := toCBufferPtr(wasm)
zkeyBuffer := toCBufferPtr(zkey)
verifKeyBuffer := toCBufferPtr(verifKey)
treeConfigBuffer := toCBufferPtr(treeConfig)
r := &RLN{}
if !bool(C.new_with_params(C.uintptr_t(depth), wasmBuffer, zkeyBuffer, verifKeyBuffer, treeConfigBuffer, &r.ptr)) {
return nil, errors.New("failed to initialize")
}
return r, nil
}
func New(depth uint, config []byte) (*RLN, error) {
r := &RLN{}
configBuffer := toCBufferPtr(config)
if !bool(C.new(C.uintptr_t(depth), configBuffer, &r.ptr)) {
return nil, errors.New("failed to initialize")
}
return r, nil
}
func (r *RLN) Flush() bool {
return bool(C.flush(r.ptr))
}
func (r *RLN) SetTree(treeHeight uint) bool {
return bool(C.set_tree(r.ptr, C.uintptr_t(treeHeight)))
}
func (r *RLN) KeyGen() []byte {
buffer := toBuffer([]byte{})
if !bool(C.key_gen(r.ptr, &buffer)) {
return nil
}
return C.GoBytes(unsafe.Pointer(buffer.ptr), C.int(buffer.len))
}
func (r *RLN) SeededKeyGen(seed []byte) []byte {
seedBuff := toCBufferPtr(seed)
buffer := toBuffer([]byte{})
if !bool(C.seeded_key_gen(r.ptr, seedBuff, &buffer)) {
return nil
}
return C.GoBytes(unsafe.Pointer(buffer.ptr), C.int(buffer.len))
}
func (r *RLN) ExtendedKeyGen() []byte {
buffer := toBuffer([]byte{})
if !bool(C.extended_key_gen(r.ptr, &buffer)) {
return nil
}
return C.GoBytes(unsafe.Pointer(buffer.ptr), C.int(buffer.len))
}
func (r *RLN) ExtendedSeededKeyGen(seed []byte) []byte {
seedBuff := toCBufferPtr(seed)
buffer := toBuffer([]byte{})
if !bool(C.seeded_extended_key_gen(r.ptr, seedBuff, &buffer)) {
return nil
}
return C.GoBytes(unsafe.Pointer(buffer.ptr), C.int(buffer.len))
}
func (r *RLN) RecoverIDSecret(proof1 []byte, proof2 []byte) ([]byte, error) {
proof1Buff := toCBufferPtr(proof1)
proof2Buff := toCBufferPtr(proof2)
var output []byte
out := toBuffer(output)
if !bool(C.recover_id_secret(r.ptr, proof1Buff, proof2Buff, &out)) {
return nil, errors.New("failed to hash")
}
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
}
func (r *RLN) Hash(input []byte) ([]byte, error) {
inpBuff := toCBufferPtr(input)
var output []byte
out := toBuffer(output)
if !bool(C.hash(inpBuff, &out)) {
return nil, errors.New("failed to hash")
}
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
}
func (r *RLN) PoseidonHash(input []byte) ([]byte, error) {
inpBuff := toCBufferPtr(input)
var output []byte
out := toBuffer(output)
if !bool(C.poseidon_hash(inpBuff, &out)) {
return nil, errors.New("error in poseidon hash")
}
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
}
func (r *RLN) GenerateRLNProof(input []byte) ([]byte, error) {
inputBuffer := toCBufferPtr(input)
var output []byte
out := toBuffer(output)
if !bool(C.generate_rln_proof(r.ptr, inputBuffer, &out)) {
return nil, errors.New("could not generate the proof")
}
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
}
func (r *RLN) VerifyWithRoots(input []byte, roots []byte) (bool, error) {
proofBuf := toCBufferPtr(input)
rootBuf := toCBufferPtr(roots)
res := C.bool(false)
if !bool(C.verify_with_roots(r.ptr, proofBuf, rootBuf, &res)) {
return false, errors.New("could not verify with roots")
}
return bool(res), nil
}
func (r *RLN) SetLeaf(index uint, idcommitment []byte) bool {
buff := toCBufferPtr(idcommitment[:])
return bool(C.set_leaf(r.ptr, C.uintptr_t(index), buff))
}
func (r *RLN) SetNextLeaf(idcommitment []byte) bool {
buff := toCBufferPtr(idcommitment[:])
return bool(C.set_next_leaf(r.ptr, buff))
}
func (r *RLN) SetLeavesFrom(index uint, idcommitments []byte) bool {
idCommBuffer := toCBufferPtr(idcommitments)
return bool(C.set_leaves_from(r.ptr, C.uintptr_t(index), idCommBuffer))
}
func (r *RLN) InitTreeWithLeaves(idcommitments []byte) bool {
idCommBuffer := toCBufferPtr(idcommitments)
return bool(C.init_tree_with_leaves(r.ptr, idCommBuffer))
}
func (r *RLN) SetMetadata(metadata []byte) bool {
metadataBuffer := toCBufferPtr(metadata)
return bool(C.set_metadata(r.ptr, metadataBuffer))
}
func (r *RLN) GetMetadata() ([]byte, error) {
var output []byte
out := toBuffer(output)
if !bool(C.get_metadata(r.ptr, &out)) {
return nil, errors.New("could not obtain the metadata")
}
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
}
func (r *RLN) AtomicOperation(index uint, leaves []byte, indices []byte) bool {
leavesBuffer := toCBufferPtr(leaves)
indicesBuffer := toCBufferPtr(indices)
return bool(C.atomic_operation(r.ptr, C.uintptr_t(index), leavesBuffer, indicesBuffer))
}
func (r *RLN) SeqAtomicOperation(leaves []byte, indices []byte) bool {
leavesBuffer := toCBufferPtr(leaves)
indicesBuffer := toCBufferPtr(indices)
return bool(C.seq_atomic_operation(r.ptr, leavesBuffer, indicesBuffer))
}
func (r *RLN) DeleteLeaf(index uint) bool {
return bool(C.delete_leaf(r.ptr, C.uintptr_t(index)))
}
func (r *RLN) GetRoot() ([]byte, error) {
var output []byte
out := toBuffer(output)
if !bool(C.get_root(r.ptr, &out)) {
return nil, errors.New("could not get the root")
}
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
}
func (r *RLN) GetLeaf(index uint) ([]byte, error) {
var output []byte
out := toBuffer(output)
if !bool(C.get_leaf(r.ptr, C.uintptr_t(index), &out)) {
return nil, errors.New("could not get the leaf")
}
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
}
func (r *RLN) LeavesSet() uint {
return uint(C.leaves_set(r.ptr))
}