// takes as input a public key and a signed message // returns whether the signature is valid or not func Verify(verificationKey PublicKey, signedMessage SignedMessage) (verified bool, err error) { // points to unsigned message after verifying var messagePointer *C.uchar messageBytes := make([]byte, len(signedMessage.Message)+1) if len(signedMessage.Message) == 0 { // must point somewhere valid, but the data won't be altered // can't point to [0] because the slice is empty messagePointer = (*C.uchar)(unsafe.Pointer(&messageBytes)) } else { messagePointer = (*C.uchar)(unsafe.Pointer(&messageBytes[0])) } // points to an int so the C function can return the message length after verifying var messageLen uint64 lenPointer := (*C.ulonglong)(unsafe.Pointer(&messageLen)) // points to the signed message as input for verification signedMessageBytes := []byte(signedMessage.CombinedMessage()) signedMessagePointer := (*C.uchar)(unsafe.Pointer(&signedMessageBytes[0])) // length of signed message, but as a C object signedMessageLen := C.ulonglong(len(signedMessageBytes)) // pointer to the public key used to sign the message verificationKeyPointer := (*C.uchar)(unsafe.Pointer(&verificationKey[0])) // verify signature success := C.crypto_sign_open(messagePointer, lenPointer, signedMessagePointer, signedMessageLen, verificationKeyPointer) verified = success == 0 return }
func SignOpen(messageOut []byte, sealedMessage []byte, pk []byte) int { support.CheckSize(messageOut, len(sealedMessage)-SignBytes(), "message output") support.CheckSize(pk, SignPublicKeyBytes(), "public key") lenMessageOut := (C.ulonglong)(len(messageOut)) return int(C.crypto_sign_open( (*C.uchar)(&messageOut[0]), (*C.ulonglong)(&lenMessageOut), (*C.uchar)(&sealedMessage[0]), (C.ulonglong)(len(sealedMessage)), (*C.uchar)(&pk[0]))) }
func CryptoSignOpen(sm []byte, pk []byte) ([]byte, int) { support.CheckSize(pk, CryptoSignPublicKeyBytes(), "public key") m := make([]byte, len(sm)-CryptoSignBytes()) var actualMSize C.ulonglong exit := int(C.crypto_sign_open( (*C.uchar)(&m[0]), (&actualMSize), (*C.uchar)(&sm[0]), (C.ulonglong)(len(sm)), (*C.uchar)(&pk[0]))) return m[:actualMSize], exit }
// verify a signed message func CryptoVerify(smsg, pk []byte) bool { smsg_buff := NewBuffer(smsg) defer smsg_buff.Free() pk_buff := NewBuffer(pk) defer pk_buff.Free() if pk_buff.size != C.crypto_sign_publickeybytes() { return false } mlen := C.ulonglong(0) msg := malloc(C.size_t(len(smsg))) defer msg.Free() smlen := C.ulonglong(smsg_buff.size) return C.crypto_sign_open(msg.uchar(), &mlen, smsg_buff.uchar(), smlen, pk_buff.uchar()) != -1 }