crypto

package module
v0.0.0-...-0b3308b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2017 License: MPL-2.0 Imports: 0 Imported by: 0

README

Build Status

DeDiS Advanced Crypto Library for Go

This package provides a toolbox of advanced cryptographic primitives for Go, targeting applications like Dissent that need more than straightforward signing and encryption. Please see the GoDoc documentation for this package for details on the library's purpose and API functionality.

Installing

First make sure you have Go version 1.3 or newer installed.

The basic crypto library requires only Go and a few third-party Go-language dependencies that can be installed automatically as follows:

go get github.com/dedis/crypto
cd $GOPATH/src/github.com/dedis/crypto
go get ./... # install 3rd-party dependencies

You should then be able to test its basic function as follows:

cd $GOPATH/src/github.com/dedis/crypto
go test -v

You can recursively test all the packages in the library as follows, keeping in mind that some sub-packages will only build if certain dependencies are satisfied as described below:

go test -v ./...

Dependencies

The library's basic functionality depends only on the Go standard library. However, parts of the library will only build if certain other, optional system packages are installed with their header files and libraries (e.g., the "-dev" version of the package). In particular:

  • crypto.openssl: This sub-package is a wrapper that builds on the OpenSSL crypto library to provide a fast, mature implementation of NIST-standardized elliptic curves and symmetric cryptosystems.

  • crypto.pbc: This is a wrapper for the Stanford Pairing-Based Crypto (PBC) library, which will of course only work if the PBC library is installed.

Issues

  • Traditionally, ECDH (Elliptic curve Diffie-Hellman) derives the shared secret from the x point only. In this framework, you can either manually retrieve the value or use the MarshalBinary method to take the combined (x, y) value as the shared secret. We recommend the latter process for new softare/protocols using this framework as it is cleaner and generalizes across differen types of groups (e.g., both integer and elliptic curves), although it will likely be incompatible with other implementations of ECDH. http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman

Documentation

Overview

Package crypto provides a toolbox of advanced cryptographic primitives, for applications that need more than straightforward signing and encryption. The cornerstone of this toolbox is the 'abstract' sub-package, which defines abstract interfaces to cryptographic primitives designed to be independent of specific cryptographic algorithms, to facilitate upgrading applications to new cryptographic algorithms or switching to alternative algorithms for experimentation purposes.

Abstract Groups and Crypto Suites

This toolkit's public-key crypto API includes an abstract.Group interface generically supporting a broad class of group-based public-key primitives including DSA-style integer residue groups and elliptic curve groups. Users of this API can thus write higher-level crypto algorithms such as zero-knowledge proofs without knowing or caring exactly what kind of group, let alone which precise security parameters or elliptic curves, are being used. The abstract group interface supports the standard algebraic operations on group elements and scalars that nontrivial public-key algorithms tend to rely on. The interface uses additive group terminology typical for elliptic curves, such that point addition is homomorphically equivalent to adding their (potentially secret) scalar multipliers. But the API and its operations apply equally well to DSA-style integer groups.

The abstract.Suite interface builds further on the abstract.Group API to represent an abstraction of entire pluggable ciphersuites, which include a group (e.g., curve) suitable for advanced public-key crypto together with a suitably matched set of symmetric-key crypto algorithms.

As a trivial example, generating a public/private keypair is as simple as:

a := suite.Scalar().Pick(random.Stream) // Alice's private key
A := suite.Point().Mul(nil, a)          // Alice's public key

The first statement picks a private key (Scalar) from a specified source of cryptographic random or pseudo-random bits, while the second performs elliptic curve scalar multiplication of the curve's standard base point (indicated by the 'nil' argument to Mul) by the scalar private key 'a'. Similarly, computing a Diffie-Hellman shared secret using Alice's private key 'a' and Bob's public key 'B' can be done via:

S := suite.Point().Mul(B, a)		// Shared Diffie-Hellman secret

Note that we use 'Mul' rather than 'Exp' here because the library uses the additive-group terminology common for elliptic curve crypto, rather than the multiplicative-group terminology of traditional integer groups - but the two are semantically equivalent and the interface itself works for both elliptic curve and integer groups. See below for more complete examples.

Higher-level Building Blocks

Various sub-packages provide several specific implementations of these abstract cryptographic interfaces. In particular, the 'nist' sub-package provides implementations of modular integer groups underlying conventional DSA-style algorithms, and of NIST-standardized elliptic curves built on the Go crypto library. The 'edwards' sub-package provides the abstract group interface using more recent Edwards curves, including the popular Ed25519 curve. The 'openssl' sub-package offers an alternative implementation of NIST-standardized elliptic curves and symmetric-key algorithms, built as wrappers around OpenSSL's crypto library.

Other sub-packages build more interesting high-level cryptographic tools atop these abstract primitive interfaces, including:

- poly: Polynomial commitment and verifiable Shamir secret splitting for implementing verifiable 't-of-n' threshold cryptographic schemes. This can be used to encrypt a message so that any 2 out of 3 receivers must work together to decrypt it, for example.

- proof: An implementation of the general Camenisch/Stadler framework for discrete logarithm knowledge proofs. This system supports both interactive and non-interactive proofs of a wide variety of statements such as, "I know the secret x associated with public key X or I know the secret y associated with public key Y", without revealing anything about either secret or even which branch of the "or" clause is true.

- anon: Anonymous and pseudonymous public-key encryption and signing, where the sender of a signed message or the receiver of an encrypted message is defined as an explicit anonymity set containing several public keys rather than just one. For example, a member of an organization's board of trustees might prove to be a member of the board without revealing which member she is.

- shuffle: Verifiable cryptographic shuffles of ElGamal ciphertexts, which can be used to implement (for example) voting or auction schemes that keep the sources of individual votes or bids private without anyone having to trust the shuffler(s) to shuffle votes/bids honestly.

Disclaimer

For now this library should currently be considered experimental: it will definitely be changing in non-backward-compatible ways, and it will need independent security review before it should be considered ready for use in security-critical applications. However, we intend to bring the library closer to stability and real-world usability as quickly as development resources permit, and as interest and application demand dictates.

As should be obvious, this library is intended the use of developers who are at least moderately knowledgeable about crypto. If you want a crypto library that makes it easy to implement "basic crypto" functionality correctly - i.e., plain public-key encryption and signing - then the NaCl/Sodium pursues this worthy goal (http://doc.libsodium.org). This toolkit's purpose is to make it possible - and preferably but not necessarily easy - to do slightly more interesting things that most current crypto libraries don't support effectively. The one existing crypto library that this toolkit is probably most comparable to is the Charm rapid prototyping library for Python (http://charm-crypto.com/).

This library incorporates and/or builds on existing code from a variety of sources, as documented in the relevant sub-packages.

Example (DiffieHellman)

This example illustrates how to use the crypto toolkit's abstract group API to perform basic Diffie-Hellman key exchange calculations, using the NIST-standard P256 elliptic curve in this case. Any other suitable elliptic curve or other cryptographic group may be used simply by changing the first line that picks the suite.

// Crypto setup: NIST-standardized P256 curve with AES-128 and SHA-256
suite := nist.NewAES128SHA256P256()

// Alice's public/private keypair
a := suite.Scalar().Pick(random.Stream) // Alice's private key
A := suite.Point().Mul(nil, a)          // Alice's public key

// Bob's public/private keypair
b := suite.Scalar().Pick(random.Stream) // Alice's private key
B := suite.Point().Mul(nil, b)          // Alice's public key

// Assume Alice and Bob have securely obtained each other's public keys.

// Alice computes their shared secret using Bob's public key.
SA := suite.Point().Mul(B, a)

// Bob computes their shared secret using Alice's public key.
SB := suite.Point().Mul(A, b)

// They had better be the same!
if !SA.Equal(SB) {
	panic("Diffie-Hellman key exchange didn't work")
}
println("Shared secret: " + SA.String())
Output:

Example (ElGamalEncryption)

This example illustrates how the crypto toolkit may be used to perform "pure" ElGamal encryption, in which the message to be encrypted is small enough to be embedded directly within a group element (e.g., in an elliptic curve point). For basic background on ElGamal encryption see for example http://en.wikipedia.org/wiki/ElGamal_encryption.

Most public-key crypto libraries tend not to support embedding data in points, in part because for "vanilla" public-key encryption you don't need it: one would normally just generate an ephemeral Diffie-Hellman secret and use that to seed a symmetric-key crypto algorithm such as AES, which is much more efficient per bit and works for arbitrary-length messages. However, in many advanced public-key crypto algorithms it is often useful to be able to embedded data directly into points and compute with them: as just one of many examples, the proactively verifiable anonymous messaging scheme prototyped in Verdict (see http://dedis.cs.yale.edu/dissent/papers/verdict-abs).

For fancier versions of ElGamal encryption implemented in this toolkit see for example anon.Encrypt, which encrypts a message for one of several possible receivers forming an explicit anonymity set.

package main

import (
	"github.com/dedis/crypto/abstract"
	"github.com/dedis/crypto/nist"
	"github.com/dedis/crypto/random"
)

func ElGamalEncrypt(suite abstract.Suite, pubkey abstract.Point, message []byte) (
	K, C abstract.Point, remainder []byte) {

	// Embed the message (or as much of it as will fit) into a curve point.
	M, remainder := suite.Point().Pick(message, random.Stream)

	// ElGamal-encrypt the point to produce ciphertext (K,C).
	k := suite.Scalar().Pick(random.Stream) // ephemeral private key
	K = suite.Point().Mul(nil, k)           // ephemeral DH public key
	S := suite.Point().Mul(pubkey, k)       // ephemeral DH shared secret
	C = S.Add(S, M)                         // message blinded with secret
	return
}

func ElGamalDecrypt(suite abstract.Suite, prikey abstract.Scalar, K, C abstract.Point) (
	message []byte, err error) {

	// ElGamal-decrypt the ciphertext (K,C) to reproduce the message.
	S := suite.Point().Mul(K, prikey) // regenerate shared secret
	M := suite.Point().Sub(C, S)      // use to un-blind the message
	message, err = M.Data()           // extract the embedded data
	return
}

/*
This example illustrates how the crypto toolkit may be used
to perform "pure" ElGamal encryption,
in which the message to be encrypted is small enough to be embedded
directly within a group element (e.g., in an elliptic curve point).
For basic background on ElGamal encryption see for example
http://en.wikipedia.org/wiki/ElGamal_encryption.

Most public-key crypto libraries tend not to support embedding data in points,
in part because for "vanilla" public-key encryption you don't need it:
one would normally just generate an ephemeral Diffie-Hellman secret
and use that to seed a symmetric-key crypto algorithm such as AES,
which is much more efficient per bit and works for arbitrary-length messages.
However, in many advanced public-key crypto algorithms it is often useful
to be able to embedded data directly into points and compute with them:
as just one of many examples,
the proactively verifiable anonymous messaging scheme prototyped in Verdict
(see http://dedis.cs.yale.edu/dissent/papers/verdict-abs).

For fancier versions of ElGamal encryption implemented in this toolkit
see for example anon.Encrypt, which encrypts a message for
one of several possible receivers forming an explicit anonymity set.
*/
func main() {
	suite := nist.NewAES128SHA256P256()

	// Create a public/private keypair
	a := suite.Scalar().Pick(random.Stream) // Alice's private key
	A := suite.Point().Mul(nil, a)          // Alice's public key

	// ElGamal-encrypt a message using the public key.
	m := []byte("The quick brown fox")
	K, C, _ := ElGamalEncrypt(suite, A, m)

	// Decrypt it using the corresponding private key.
	mm, err := ElGamalDecrypt(suite, a, K, C)

	// Make sure it worked!
	if err != nil {
		panic("decryption failed: " + err.Error())
	}
	if string(mm) != string(m) {
		panic("decryption produced wrong output: " + string(mm))
	}
	println("Decryption succeeded: " + string(mm))

}
Output:

Directories

Path Synopsis
This package defines abstract interfaces for advanced cryptographic primitives.
This package defines abstract interfaces for advanced cryptographic primitives.
Package anon implements cryptographic primitives for anonymous communication.
Package anon implements cryptographic primitives for anonymous communication.
Package base64 implements base64 encoding as specified by RFC 4648.
Package base64 implements base64 encoding as specified by RFC 4648.
aes
Package aes implements the general Cipher interface using AES, SHA2, and HMAC.
Package aes implements the general Cipher interface using AES, SHA2, and HMAC.
bench
This package exists runs comparative benchmarks across several alternative Cipher implementations.
This package exists runs comparative benchmarks across several alternative Cipher implementations.
norx
Package NORX implements the experimental NORX cipher.
Package NORX implements the experimental NORX cipher.
sha3
Package sha3 implements the SHA-3 fixed-output-length hash functions and the SHAKE variable-output-length hash functions defined by FIPS-202.
Package sha3 implements the SHA-3 fixed-output-length hash functions and the SHAKE variable-output-length hash functions defined by FIPS-202.
A clique protocol is an abstraction for a cryptographic protocol in which every participant knows about and interacts directly in lock-step with every other participant in the clique.
A clique protocol is an abstraction for a cryptographic protocol in which every participant knows about and interacts directly in lock-step with every other participant in the clique.
Package cosi is the Collective Signing implementation according to the paper of Bryan Ford: http://arxiv.org/pdf/1503.08768v1.pdf .
Package cosi is the Collective Signing implementation according to the paper of Bryan Ford: http://arxiv.org/pdf/1503.08768v1.pdf .
Package ed25519 provides an optimized Go implementation of a Twisted Edwards curve that is isomorphic to Curve25519.
Package ed25519 provides an optimized Go implementation of a Twisted Edwards curve that is isomorphic to Curve25519.
This package contains several implementations of Twisted Edwards Curves, from general and unoptimized to highly specialized and optimized.
This package contains several implementations of Twisted Edwards Curves, from general and unoptimized to highly specialized and optimized.
Package group contains generic facilities for implementing cryptographic groups.
Package group contains generic facilities for implementing cryptographic groups.
Package hash provides utility functions to process complex data types, like data streams, files, or sequences of structs of different types.
Package hash provides utility functions to process complex data types, like data streams, files, or sequences of structs of different types.
Package dissent/math contains big.Int arithmetic functions that probably belong in Go's math/big package.
Package dissent/math contains big.Int arithmetic functions that probably belong in Go's math/big package.
Package nego implements cryptographic negotiation and secret entrypoint finding.
Package nego implements cryptographic negotiation and secret entrypoint finding.
Package nist implements cryptographic groups and ciphersuites based on the NIST standards, using Go's built-in crypto library.
Package nist implements cryptographic groups and ciphersuites based on the NIST standards, using Go's built-in crypto library.
This package implements the Deal cryptographic primitive, which is based * on poly/sharing.go * * Failures are frequent in large-scale systems.
This package implements the Deal cryptographic primitive, which is based * on poly/sharing.go * * Failures are frequent in large-scale systems.
This package provides functionality to create and verify non-interactive zero-knowledge (NIZK) proofs for the equality (EQ) of discrete logarithms (DL).
This package provides functionality to create and verify non-interactive zero-knowledge (NIZK) proofs for the equality (EQ) of discrete logarithms (DL).
Package rand provides facilities for generating random or pseudorandom cryptographic objects.
Package rand provides facilities for generating random or pseudorandom cryptographic objects.
Package share implements Shamir secret sharing and polynomial commitments.
Package share implements Shamir secret sharing and polynomial commitments.
dkg
Package dkg implements the protocol described in "Secure Distributed Key Generation for Discrete-Log Based Cryptosystems" by R. Gennaro, S. Jarecki, H. Krawczyk, and T. Rabin.
Package dkg implements the protocol described in "Secure Distributed Key Generation for Discrete-Log Based Cryptosystems" by R. Gennaro, S. Jarecki, H. Krawczyk, and T. Rabin.
dss
DSS implements the Distributed Schnorr Signature protocol from the paper "Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates".
DSS implements the Distributed Schnorr Signature protocol from the paper "Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates".
pvss
Package pvss implements public verifiable secret sharing as introduced in "A Simple Publicly Verifiable Secret Sharing Scheme and its Application to Electronic Voting" by Berry Schoenmakers.
Package pvss implements public verifiable secret sharing as introduced in "A Simple Publicly Verifiable Secret Sharing Scheme and its Application to Electronic Voting" by Berry Schoenmakers.
vss
Package vss implements the verifiable secret sharing scheme from the paper "Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates".
Package vss implements the verifiable secret sharing scheme from the paper "Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates".
Package shuffle implements Andrew Neff's verifiable shuffle proof scheme.
Package shuffle implements Andrew Neff's verifiable shuffle proof scheme.
This package contains lists of ciphersuites defined elsewhere in other packages.
This package contains lists of ciphersuites defined elsewhere in other packages.
Package test contains generic testing and benchmarking infrastructure for cryptographic groups and ciphersuites.
Package test contains generic testing and benchmarking infrastructure for cryptographic groups and ciphersuites.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL