diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js
index a66decdc..7404cbe6 100644
--- a/src/crypto/public_key/elliptic/oid_curves.js
+++ b/src/crypto/public_key/elliptic/oid_curves.js
@@ -182,8 +182,11 @@ class CurveWithOID {
       case 'node':
         return nodeGenKeyPair(this.name);
       case 'curve25519Legacy': {
+        // the private key must be stored in big endian and already clamped: https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#section-5.5.5.6.1.1-3
         const { k, A } = await ecdhXGenerate(enums.publicKey.x25519);
         const privateKey = k.slice().reverse();
+        privateKey[0] = (privateKey[0] & 127) | 64;
+        privateKey[31] &= 248;
         const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), A]);
         return { publicKey, privateKey };
       }
diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js
index 54408418..b44c8a3f 100644
--- a/test/crypto/ecdh.js
+++ b/test/crypto/ecdh.js
@@ -1,3 +1,4 @@
+import x25519 from '@openpgp/tweetnacl';
 import sinon from 'sinon';
 import { use as chaiUse, expect } from 'chai';
 import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import
@@ -67,6 +68,16 @@ export default () => describe('ECDH key exchange @lightweight', function () {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   ]);
 
+  it('Generated legacy x25519 secret scalar is stored clamped', async function () {
+    const curve = new elliptic_curves.CurveWithOID(openpgp.enums.curve.curve25519Legacy);
+    const { privateKey, publicKey } = await curve.genKeyPair();
+    const clampedKey = privateKey.slice();
+    clampedKey[0] = (clampedKey[0] & 127) | 64;
+    clampedKey[31] &= 248;
+    expect(privateKey).to.deep.equal(clampedKey);
+    const { publicKey: expectedPublicKey } = x25519.box.keyPair.fromSecretKey(privateKey.slice().reverse());
+    expect(publicKey.subarray(1)).to.deep.equal(expectedPublicKey);
+  });
   it('Invalid curve oid', function (done) {
     expect(decrypt_message(
       '', 2, 7, [], [], [], [], []