[Pkg-privacy-commits] [Git][pkg-privacy-team/obfs4proxy][master] 9 commits: Add myself to Uploaders

Micah Anderson (@micah) micah at debian.org
Wed Oct 5 16:39:18 BST 2022



Micah Anderson pushed to branch master at Privacy Maintainers / obfs4proxy


Commits:
48750fdf by Micah Anderson at 2022-10-05T11:18:57-04:00
Add myself to Uploaders

- - - - -
1092590a by Micah Anderson at 2022-10-05T11:20:52-04:00
Bump Standards-Version

- - - - -
2b066f86 by Micah Anderson at 2022-10-05T11:22:38-04:00
Add Ruben Pollen to Uploaders

- - - - -
33296102 by Micah Anderson at 2022-10-05T11:24:06-04:00
Update patches/remove_git to remove the trailing .git

- - - - -
08a20dea by Micah Anderson at 2022-10-05T11:24:54-04:00
Update debian/watch to support new version

- - - - -
f670d556 by Micah Anderson at 2022-10-05T11:29:23-04:00
Prepare for release

- - - - -
267eae32 by Micah Anderson at 2022-10-05T11:32:02-04:00
New upstream version 0.0.14
- - - - -
21c95fdd by Micah Anderson at 2022-10-05T11:32:02-04:00
Update upstream source from tag 'upstream/0.0.14'

Update to upstream version '0.0.14'
with Debian dir eab9b20ef38de8bd7bc5266a8175c1ee4a2e7702
- - - - -
debe4db4 by Micah Anderson at 2022-10-05T11:32:43-04:00
Merge branch 'debian/0.0.14-1'

- - - - -


9 changed files:

- ChangeLog
- common/ntor/ntor.go
- common/ntor/ntor_test.go
- debian/changelog
- debian/control
- debian/patches/remove_git.diff
- debian/watch
- internal/x25519ell2/x25519ell2.go
- obfs4proxy/obfs4proxy.go


Changes:

=====================================
ChangeLog
=====================================
@@ -1,3 +1,7 @@
+Changes in version 0.0.14 - 2022-09-04:
+ - Fixed the incompete previous fix to the Elligator 2 subgroup issue (Thanks
+   to David Fifield).
+
 Changes in version 0.0.13 - 2022-02-04:
  - Stop using utls entirely for TLS signature normalization (meek_lite).
  - Stop pinning the certificate chain for default bridges (meek_lite).


=====================================
common/ntor/ntor.go
=====================================
@@ -273,9 +273,6 @@ func NewKeypair(elligator bool) (*Keypair, error) {
 			return nil, err
 		}
 		digest := sha512.Sum512(priv)
-		digest[0] &= 248
-		digest[31] &= 127
-		digest[31] |= 64
 		copy(priv, digest[:])
 
 		if elligator {


=====================================
common/ntor/ntor_test.go
=====================================
@@ -30,6 +30,10 @@ package ntor
 import (
 	"bytes"
 	"testing"
+
+	"filippo.io/edwards25519"
+	"filippo.io/edwards25519/field"
+	"gitlab.com/yawning/edwards25519-extra.git/elligator2"
 )
 
 // TestNewKeypair tests Curve25519/Elligator keypair generation.
@@ -126,6 +130,138 @@ func TestHandshake(t *testing.T) {
 	}
 }
 
+// TestPublicKeySubgroup tests that Elligator representatives produced by
+// NewKeypair map to public keys that are not always on the prime-order subgroup
+// of Curve25519. (And incidentally that Elligator representatives agree with
+// the public key stored in the Keypair.)
+//
+// See discussion under "Step 2" at https://elligator.org/key-exchange.
+func TestPublicKeySubgroup(t *testing.T) {
+	// We will test the public keys that comes out of NewKeypair by
+	// multiplying each one by L, the order of the prime-order subgroup of
+	// Curve25519, then checking the order of the resulting point. The error
+	// condition we are checking for specifically is output points always
+	// having order 1, which means that public keys are always on the
+	// prime-order subgroup of Curve25519, which would make Elligator
+	// representatives distinguishable from random. More generally, we want
+	// to ensure that all possible output points of low order are covered.
+	//
+	// We have to do some contortions to conform to the interfaces we use.
+	// We do scalar multiplication by L using Edwards coordinates, rather
+	// than the Montgomery coordinates output by Keypair.Public and
+	// Representative.ToPublic, because the Montgomery-based
+	// crypto/curve25519.X25519 clamps the scalar to be a multiple of 8,
+	// which would not allow us to use the scalar we need. The Edwards-based
+	// ScalarMult only accepts scalars that are strictly less than L; we
+	// work around this by multiplying the point by L - 1, then adding the
+	// point once to the product.
+
+	scalarOrderMinus1, err := edwards25519.NewScalar().SetCanonicalBytes(
+		// This is the same as scMinusOne in filippo.io/edwards25519.
+		// https://github.com/FiloSottile/edwards25519/blob/v1.0.0/scalar.go#L34
+		[]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16},
+	)
+	if err != nil {
+		panic(err)
+	}
+	// Returns a new edwards25519.Point that is v multiplied by the subgroup
+	// order.
+	scalarMultOrder := func(v *edwards25519.Point) *edwards25519.Point {
+		p := new(edwards25519.Point)
+		// v * (L - 1) + v => v * L
+		p.ScalarMult(scalarOrderMinus1, v)
+		p.Add(p, v)
+		return p
+	}
+
+	// Generates a new Keypair using NewKeypair, and returns the Keypair
+	// along, with its public key as a newly allocated edwards25519.Point.
+	generate := func() (*Keypair, *edwards25519.Point) {
+		kp, err := NewKeypair(true)
+		if err != nil {
+			panic(err)
+		}
+
+		// We will be using the Edwards representation of the public key
+		// (mapped from the Elligator representative) for further
+		// processing. But while we're here, check that the Montgomery
+		// representation output by Representative agrees with the
+		// stored public key.
+		if *kp.Representative().ToPublic() != *kp.Public() {
+			t.Fatal(kp.Representative().ToPublic(), kp.Public())
+		}
+
+		// Do the Elligator map in Edwards coordinates.
+		var clamped [32]byte
+		copy(clamped[:], kp.Representative().Bytes()[:])
+		clamped[31] &= 63
+		repr, err := new(field.Element).SetBytes(clamped[:])
+		if err != nil {
+			panic(err)
+		}
+		ed := elligator2.EdwardsFlavor(repr)
+		if !bytes.Equal(ed.BytesMontgomery(), kp.Public().Bytes()[:]) {
+			panic("Failed to derive an equivalent public key in Edwards coordinates")
+		}
+		return kp, ed
+	}
+
+	// These are all the points of low order that may result from
+	// multiplying an Elligator-mapped point by L. We will test that all of
+	// them are covered.
+	lowOrderPoints := [][32]byte{
+		/* order 1 */ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		/* order 2 */ {236, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127},
+		/* order 4 */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		/* order 4 */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128},
+		/* order 8 */ {38, 232, 149, 143, 194, 178, 39, 176, 69, 195, 244, 137, 242, 239, 152, 240, 213, 223, 172, 5, 211, 198, 51, 57, 177, 56, 2, 136, 109, 83, 252, 5},
+		/* order 8 */ {38, 232, 149, 143, 194, 178, 39, 176, 69, 195, 244, 137, 242, 239, 152, 240, 213, 223, 172, 5, 211, 198, 51, 57, 177, 56, 2, 136, 109, 83, 252, 133},
+		/* order 8 */ {199, 23, 106, 112, 61, 77, 216, 79, 186, 60, 11, 118, 13, 16, 103, 15, 42, 32, 83, 250, 44, 57, 204, 198, 78, 199, 253, 119, 146, 172, 3, 122},
+		/* order 8 */ {199, 23, 106, 112, 61, 77, 216, 79, 186, 60, 11, 118, 13, 16, 103, 15, 42, 32, 83, 250, 44, 57, 204, 198, 78, 199, 253, 119, 146, 172, 3, 250},
+	}
+	counts := make(map[[32]byte]int)
+	for _, b := range lowOrderPoints {
+		counts[b] = 0
+	}
+	// Assuming a uniform distribution of representatives, the probability
+	// that a specific low-order point will not be covered after n trials is
+	// (7/8)^n. The probability that *any* of the 8 low-order points will
+	// remain uncovered after n trials is at most 8 times that, 8*(7/8)^n.
+	// We must do at least log((1e-12)/8)/log(7/8) = 222.50 trials, in the
+	// worst case, to ensure a false error rate of less than 1 in a
+	// trillion. In practice, we keep track of the number of covered points
+	// and break the loop when it reaches 8, so when representatives are
+	// actually uniform we will usually run much fewer iterations.
+	numCovered := 0
+	for i := 0; i < 225; i++ {
+		kp, pk := generate()
+		v := scalarMultOrder(pk)
+		var b [32]byte
+		copy(b[:], v.Bytes())
+		if _, ok := counts[b]; !ok {
+			t.Fatalf("map(%x)*order yielded unexpected point %v",
+				*kp.Representative().Bytes(), b)
+		}
+		counts[b]++
+		if counts[b] == 1 {
+			// We just covered a new point for the first time.
+			numCovered++
+			if numCovered == len(lowOrderPoints) {
+				break
+			}
+		}
+	}
+	for _, b := range lowOrderPoints {
+		count, ok := counts[b]
+		if !ok {
+			panic(b)
+		}
+		if count == 0 {
+			t.Errorf("low-order point %x not covered", b)
+		}
+	}
+}
+
 // Benchmark Client/Server handshake.  The actual time taken that will be
 // observed on either the Client or Server is half the reported time per
 // operation since the benchmark does both sides.


=====================================
debian/changelog
=====================================
@@ -1,3 +1,17 @@
+obfs4proxy (0.0.14-1) unstable; urgency=high
+
+  [ Micah Anderson ]
+  * Add myself to Uploaders
+
+  [ Ruben Pollan ]
+  * Bump Standards-Version to 4.6.1, no changes.
+  * Add myself to Uploaders
+  * Update patches/remove_git to remove the trailing .git
+  * Update debian/watch file for new watch version
+  * New upstream version 0.0.14, urgency high to fix a security issue
+
+ -- Micah Anderson <micah at debian.org>  Wed, 05 Oct 2022 11:17:32 -0400
+
 obfs4proxy (0.0.13-1) unstable; urgency=low
 
   [ Debian Janitor ]


=====================================
debian/control
=====================================
@@ -3,7 +3,9 @@ Maintainer: Debian Privacy Tools Maintainers <pkg-privacy-maintainers at lists.alio
 Uploaders:
  Jérémy Bobbio <lunar at debian.org>,
  Ximin Luo <infinity0 at debian.org>,
- Ana Custura <ana at netstat.org.uk>
+ Ana Custura <ana at netstat.org.uk>,
+ Micah Anderson <micah at debian.org>,
+ Ruben Pollan <meskio at sindominio.net>
 Section: net
 Priority: optional
 Build-Depends:
@@ -17,7 +19,7 @@ Build-Depends:
  golang-siphash-dev,
  golang-gitlab-yawning-edwards25519-extra-dev,
  golang-filippo-edwards25519-dev (>= 1.0.0~rc1+git20210721)
-Standards-Version: 4.5.0
+Standards-Version: 4.6.1
 Vcs-Git: https://salsa.debian.org/pkg-privacy-team/obfs4proxy.git
 Vcs-Browser: https://salsa.debian.org/pkg-privacy-team/obfs4proxy
 XS-Go-Import-Path: gitlab.com/yawning/obfs4.git


=====================================
debian/patches/remove_git.diff
=====================================
@@ -4,6 +4,17 @@ Description: Remove .git suffix from imports
 Author: Ana Custura <ana at netstat.org.uk>
 ---
 This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/common/ntor/ntor_test.go
++++ b/common/ntor/ntor_test.go
+@@ -33,7 +33,7 @@ import (
+ 
+ 	"filippo.io/edwards25519"
+ 	"filippo.io/edwards25519/field"
+-	"gitlab.com/yawning/edwards25519-extra.git/elligator2"
++	"gitlab.com/yawning/edwards25519-extra/elligator2"
+ )
+ 
+ // TestNewKeypair tests Curve25519/Elligator keypair generation.
 --- a/internal/x25519ell2/x25519ell2.go
 +++ b/internal/x25519ell2/x25519ell2.go
 @@ -23,7 +23,7 @@


=====================================
debian/watch
=====================================
@@ -1,4 +1,4 @@
-version=3
+version=4
 opts="uversionmangle=s/-(rc)/~$1/,pgpsigurlmangle=s/$/.asc/" \
 	https://people.torproject.org/~yawning/releases/obfs4proxy/ \
 	obfs4proxy-(.+)\.tar\.[^.]+


=====================================
internal/x25519ell2/x25519ell2.go
=====================================
@@ -144,6 +144,10 @@ func uToRepresentative(representative *[32]byte, u *field.Element, tweak byte) b
 // Note that this function will fail and return false for about
 // half of private keys.
 //
+// The `privateKey` input MUST be the full 32-bytes of entropy
+// (X25519-style "clamping" will result in non-uniformly distributed
+// representatives).
+//
 // WARNING: The underlying scalar multiply explicitly does not clear
 // the cofactor, and thus the public keys will be different from
 // those produced by normal implementations.


=====================================
obfs4proxy/obfs4proxy.go
=====================================
@@ -50,7 +50,7 @@ import (
 )
 
 const (
-	obfs4proxyVersion = "0.0.13"
+	obfs4proxyVersion = "0.0.14"
 	obfs4proxyLogFile = "obfs4proxy.log"
 	socksAddr         = "127.0.0.1:0"
 )



View it on GitLab: https://salsa.debian.org/pkg-privacy-team/obfs4proxy/-/compare/25a6234c08f7406acb47be28b043aa46fbb6b69c...debe4db43043d2291a3ed85380ec7453c14ecf0c

-- 
View it on GitLab: https://salsa.debian.org/pkg-privacy-team/obfs4proxy/-/compare/25a6234c08f7406acb47be28b043aa46fbb6b69c...debe4db43043d2291a3ed85380ec7453c14ecf0c
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-privacy-commits/attachments/20221005/d008be0a/attachment-0001.htm>


More information about the Pkg-privacy-commits mailing list