deltaLink not provided on last page of results when data annotations are included

I'm using Change Tracking to synchronize data from the Web API to another system, per https://docs.microsoft.com/en-us/dynamics365/customer-engagement/admin/enable-change-tracking-control-data-synchronization.
When I include the Prefer: "odata.include-annotations="OData.Community.Display.V1.FormattedValue" header, and formatted lookup values are included, the<EMAIL_ADDRESS>is not present on the last page of data.
Version 8.2

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: a077afea-0218-d8e3-6112-95ea4bb04501
Version Independent ID: 00ba7831-fe82-4f86-2864-311a7b8375b9
Content: Query Data using the Web API (Common Data Service) - PowerApps
Content Source: powerapps-docs/developer/common-data-service/webapi/query-data-web-api.md
Service: powerapps
GitHub Login: @brandonsimons
Microsoft Alias: jdaly

@tourvi Please try out the following Web API request:
GET [Organization URI]/api/data/v9.0/accounts?$select=name,accountnumber,telephone1,fax HTTP/1.1
Prefer: odata.track-changes
Cache-Control: no-cache
OData-Version: 4.0
Content-Type: application/json

@odata.deltaLink value is returned when you include the header Prefer: odata.track-changes in your request.
Please comment below if this does not solve your issue.

@tourvi I tried using header Prefer: odata.include-annotations=OData.Community.Display.V1.FormattedValue in my change tracking request with a v9.1 online instance and it returned @odata.deltaLink in the response.

@susikka I don't have a v9.1 instance to test with, but it is not there in v8.2

@tourvi Hi, I have referred this issue to the feature dev team. Please stand by till further updates on this.

I've verified that this works for v9 using this:
Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue",odata.track-changes
You must separate the two Prefer options with a comma. See Stack overflow: Standard for adding multiple values of a single HTTP Header to a request or response
Can't speak to v8, I don't have an on-premise instance available to test with.
But if you don't get the same results, then you ought to open a support request.
These are the v9 docs, so discussion of how v8 behaves will not be included here.
v8 docs are here: https://docs.microsoft.com/en-us/previous-versions/dynamicscrm-2016/developers-guide/gg334767(v=crm.8)
See the attached example file captured using Fiddler
Issue 439 example.txt

@susikka I've closed this with the comment above. Action items would be to include guidance about how to include multiple Prefer headers as explained in the comment.

Re-opening so that docs can be updated with the missing information that appears to be the root of this issue.

Part of the issue appears to be expectations. @tourvi  says:

When I include the Prefer: "odata.include-annotations="OData.Community.Display.V1.FormattedValue" header, and formatted lookup values are included, the<EMAIL_ADDRESS>is not present on the last page of data.

So it sounds like he is expecting the delta link to appear in the last page of data.
But the results I think he should expect is that the entire result set is the delta link AND it includes formatted values. For example:
{
<EMAIL_ADDRESS>"https://[your org].api.crm.dynamics.com/api/data/v9.1/$metadata#accounts(name,donotpostalmail,accountratingcode,numberofemployees,revenue)",
<EMAIL_ADDRESS>"https://[your org].api.crm.dynamics.com/api/data/v9.1/accounts?$select=name,donotpostalmail,accountratingcode,numberofemployees,revenue&$deltatoken=17129693%2109%2f02%2f2019%2017%3a43%3a29",
    "value": [
        {
<EMAIL_ADDRESS>"W/\"11738241\"",
            "name": "Litware, Inc. (sample)",
<EMAIL_ADDRESS>"Allow",
            "donotpostalmail": false,
<EMAIL_ADDRESS>"Default Value",
            "accountratingcode": 1,
<EMAIL_ADDRESS>"6,000",
            "numberofemployees": 6000,
<EMAIL_ADDRESS>"$20,000.00",
            "revenue": 20000.0000,
            "accountid": "7e4ecc5c-8bab-e611-80f5-3863bb2e03e0",
<EMAIL_ADDRESS>"US Dollar",
            "_transactioncurrencyid_value": "228f42f8-e646-e111-8eb7-78e7d162ced1"
        }
    ]
}

Not sure why @tapanm-MSFT assigned this dev topic to me. Assigning to Peter.

Not sure why @tapanm-MSFT assigned this dev topic to me. Assigning to Peter.

@phecke - see my previous comment.

@phecke - see my previous comment.

@tourvi Thanks for your feedback. We are closing this issue because we are either unable to find relevant information or reproduce this. If you're still experiencing the issue described here, please reopen or create a new issue.


[BugFix] fix array_has_generic DCHECK error

Fixes #issue
What type of PR is this:

[x] BugFix
[ ] Feature
[ ] Enhancement
[ ] Refactor
[ ] UT
[ ] Doc
[ ] Tool

Checklist:

[x] I have added test cases for my bug fix or my new feature
[ ] This pr will affect users' behaviors
[ ] This pr needs user documentation (for new or modified features or behaviors)

[ ] I have added documentation for my new feature or new function

Bugfix cherry-pick branch check:

[x] I have checked the version labels which the pr will be auto-backported to the target branch

[x] 3.1
[x] 3.0
[x] 2.5
[ ] 2.4

Where are the test cases?

@Mergifyio backport branch-3.1

@Mergifyio backport branch-3.0

@Mergifyio backport branch-2.5

https://github.com/Mergifyio backport branch-2.4


Suggested layout for sysroot for bootc integration

Talking with Allison, when flushed the following potential design for the sysroot layout which would allow us to transition existing ostree based bootc systems to pure composefs ones:
.
├── composefs
│   ├── images
│   ├── objects
│   └── streams
├── ostree
│   └── deploy
│       └── fedora
│           ├── deploy
│           │   └── hash.0
│           └── var
└── state
    ├── deploy
    │   ├── composefshash0
    │   │   ├── etc
    │   │   └── var -> ../../../ostree/deploy/fedora/var
    │   └── composefshash1
    │       ├── etc
    │       └── var -> ../../os/fedora/var
    └── os
        └── fedora
            └── var

Notes

we're not sure if /state should be toplevel or if it should live in /composefs/.  This is considered an open question.
we normally want the composefs ID alone to select the state as well.  Things get complicated with UKIs if we have the ability to have multiple sets of state that should be accessible from a single bootable image.

but, for unusual situations where we can modify the kernel commandline, we might consider a state= argument that explicitly selects a different state directory

we assume that a given composefs image will correspond to a single OS (in the ostree stateroot sense).  That lets us consolidate all deployments in a single namespace.
on boot, we open the /state/ directory that corresponds to the composefs= argument (or maybe state= argument).  Inside of that directory might exist etc and var either as directories or symlinks.  If they are directories, we mount them.  If they are symlinks, we mount what they point at.  That supports flexibility over different scenarios:

the usual situation is that we want to share one /var per OS.  The diagram above illustrates how that would look (/state/os/fedora, with symlinks from each deployment pointing to it eg. composefshash1)
sharing a /var with a sysroot from ostree, very useful for migrating or sharing (eg. composefshash0)
per-deployment /var (possibly created using btrfs snapshots on the sysroot filesystem directly)
no /var: if /var is mounted from a separate partition using /etc/fstab or GPT or otherwise by systemd
we could even mount the entire /sysroot itself as /var if we wanted

the main point here is that this is decided/managed by deployment code.  As the system is booting it just looks in the state directory and does what it's told.

About /etc
In theory /etc is handled in exactly the same way as /var during boot.  In practice, we expect there to be really only one way this is done at deployment: the usual three-way merge as currently performed by ostree, and in a very similar way.  We can support migrating from an existing ostree system in this way, since this is inherently a copy in any case.  @travier thinks that we should rewrite this algorithm ("it's not so hard...") in Rust as part of bootc, and that seems reasonable to me — it also sounds like he was volunteering me for the job.
To support the three-way merge, we plan to move /etc to /usr/etc in the in-memory filesystem tree during creation of the composefs, creating an empty /etc in its place — similar to what bootc does now when importing to ostree.  That will happen probably just after the SELinux relabelling process.  This is another way that "bootable" composefs will vary wrt. composefs that we create for running containers.  See #35.
I'm not sure what the merge process will look like exactly.  Obviously we'll read the existing /etc from the filesystem and also write the new merged /etc to the filesystem, but how will we find the new /usr/etc from the new system image?  There are two main options:

access them via the in-memory filesystem API
mount the composefs of the to-be-booted OS image and access them that way

Note: depending on how we approach this, it might be possible to avoid having /usr/etc.  For example, we could leave it at /etc and mount over top of it at run time (but still see it during deploy time) or we could exclude /etc/ entirely from the created image, replacing it with just the empty directory (since we'd still have access to the files via the in-memory filesystem image).
About kernels/bootloader entries
This might be difficult because apparently ostree doesn't like to share access to /boot.  This is the part that we fleshed out the least.  Probably we need bootc to mediate here.

I'm starting to look into merge_configuration_from() in libostree.

Related to merging /etc see also https://github.com/uapi-group/specifications/issues/76#issuecomment-2379094983 - I've been meaning to look at the Flatcar use of overlayfs here.

Related to merging /etc see also uapi-group/specifications#76 (comment) - I've been meaning to look at the Flatcar use of overlayfs here.

I've read this comment.  It's a good sort of "state of the art" overview.  I think it would indeed be worth looking into the flatcar approach a bit and seeing if we can use that instead of writing our own merge code.  I hadn't considered that ostree is maybe the way that it is only because overlayfs wasn't around at the time...
In any case, whatever we spec out, it ought to accommodate this approach.


Scrolling through chart preview on certain charts causes a loud peaking noise

Describe the bug
title, definitely remember it happening to other charts but this one comes to mind
To Reproduce
Steps to reproduce the behavior:

Go to the solo difficulty of Phase 1 in midare 2
open chart preview
click anywhere on the preview selector
hear loud noise

Expected behavior
the game should just skip to wherever you selected and not play an extremely loud noise
0.69.1 public release

This happening usually depends on the type/bitrate of the audio


[Bug Report] -

Describe the bug.
The youtube video link for uptane is no longer available. We really should host a video under the uptane channel which we control.
Describe the steps to reproduce the behavior.
No response
Expected behavior.
No response
Screenshots.
No response
Operating environment
No response
What browsers are you seeing the problem on?
No response
Additional context
No response

Closed as resloved


SystemJS Unexpected token , AngularFireModule

am trying to integrate angularfire2 with my angular 2 applications .
but am getting error while starting the application in browser .
i have tried a sample component like this one : http://stackoverflow.com/questions/39067832/accessing-firebase-storage-with-angularfire2-angular2-rc-5
this is waht am getting in the browser .

in app.module.ts file i have imported AngularFireModule like this  import {AngularFireModule} from 'angularfire2'
as per the app.module.js line 28 we are referring angularfire2
var angularfire2_1 = require("angularfire2");
so i hpe there an issue with angularfire2.
versions am using :+1:
"@angular/core": "~2.4.0",
"angularfire2": "^2.0.0-beta.8",

@AnsarSamad are you using the Angular CLI to scaffold your project?

All issues have to follow the issue template provided. I understand this is asking a lot and is generally annoying when you feel your question is straightforward, but just trust that it's critical to keep things streamlined and manageable for our team. Note that how-to questions are better suited for Stack Overflow or a discussion group.


Warn users when upgrading kubernetes version will break an installed extension

When an extension does not run on a given Kubernetes version the UI should warn the user when upgrading to that Kubernetes version.

this is also to look into extensions installed, so that when we update the k8s version, we shouldn't load the extension(s) if they are incompatible with the current k8s version

This is to look into extensions installed, we update the k8s version, then check if extension is still loaded

UPDATE: local cluster edition belongs to ember world, which only uses Norman, therefore we don't have access to the list of extensions installed on ember. With this, we cannot display a banner (item 1)) before updating the kube version on local cluster edit. Only 2) is doable.

UPDATE: point 2) isn't also doable at this point because the meta information at load time for a plugin doesn't include any annotations, therefore we cannot prevent the loading of an extension.

After chatting with @richard-cox , we decided to move this out to v2.8-next1 as it's not considered a priority and is backend blocked.
Will create backend issues for this and update the description accordingly.
FYI @gaktive

description updated. Backend blocked issue. @richard-cox @jordojordo @codyrancher

For internal coordination, SURE-8095 is our reference.

It's possible that this is resolved via other means now. Will look more in-depth for 2.11.0 before closing but we have a mechanism to detect k8s versions post-install now.

I think we can close this one in light of the effort to improve the extensions gating with https://github.com/rancher/dashboard/pull/12071 + the fact that we now have a proper kube version check


README.md

#1
BIP: 38
Title: Passphrase-protected private key
Authors: uvhw
supercute<EMAIL_ADDRESS>Status: Draft (Some confusion applies: The announcements for this never made it to the list, so it hasn't had public discussion)
Type: Standards Track
Created: 2012-11-20

==Abstract==
A method is proposed for encrypting and encoding a passphrase-protected Bitcoin private key record in the form of a 58-character Base58Check-encoded printable string.  Encrypted private key records are intended for use on paper wallets and physical Bitcoins.  Each record string contains all the information needed to reconstitute the private key except for a passphrase, and the methodology uses salting and ''scrypt'' to resist brute-force attacks.
The method provides two encoding methodologies - one permitting any known private key to be encrypted with any passphrase, and another permitting a shared private key generation scheme where the party generating the final key string and its associated Bitcoin address (such as a physical bitcoin manufacturer) knows only a string derived from the original passphrase, and where the original passphrase is needed in order to actually redeem funds sent to the associated Bitcoin address.
A 32-bit hash of the resulting Bitcoin address is encoded in plaintext within each encrypted key, so it can be correlated to a Bitcoin address with reasonable probability by someone not knowing the passphrase.  The complete Bitcoin address can be derived through successful decryption of the key record.
==Motivation==
The motivation to make this proposal stems from observations of the way physical bitcoins and paper wallets are used.
An issuer of physical bitcoins must be trustworthy and trusted.  Even if trustworthy, users are rightful to be skeptical about a third party with theoretical access to take their funds.  A physical bitcoin that cannot be compromised by its issuer is always more intrinsically valuable than one that can.
A two-factor physical bitcoin solution is highly useful to individuals and organizations wishing to securely own bitcoins without any risk of electronic theft and without the responsibility of climbing the technological learning curve necessary to produce such an environment themselves.  Two-factor physical bitcoins allow a secure storage solution to be put in a box and sold on the open market, greatly enlarging the number of people who are able to securely store bitcoins.
Existing methodologies for creating two-factor physical bitcoins are limited and cumbersome.  At the time of this proposal, a user could create their own private key, submit the public key to the physical bitcoin issuer, and then receive a physical bitcoin that must be kept together with some sort of record of the user-generated private key, and finally, must be redeemed through a tool.  The fact that the physical bitcoin must be kept together with a user-produced private key negates much of the benefit of the physical bitcoin - the user may as well just print and maintain a private key.
A standardized password-protected private key format makes acquiring and redeeming two-factor physical bitcoins simpler for the user.  Instead of maintaining a private key that cannot be memorized, the user may choose a passphrase of their choice.  The passphrase may be much shorter than the length of a typical private key, short enough that they could use a label or engraver to permanently commit their passphrase to their physical Bitcoin piece once they have received it.  By adopting a standard way to encrypt a private key, we maximize the possibility that they'll be able to redeem their funds in the venue of their choice, rather than relying on an executable redemption tool they may not wish to download.
Password and passphrase-protected private keys enable new practical use cases for sending bitcoins from person to person.  Someone wanting to send bitcoins through postal mail could send a password-protected paper wallet and give the recipient the passphrase over the phone or e-mail, making the transfer safe from interception of either channel.  A user of paper wallets or Bitcoin banknote-style vouchers ("cash") could carry funded encrypted private keys while leaving a copy at home as an element of protection against accidental loss or theft.  A user of paper wallets who leaves bitcoins in a bank vault or safety deposit box could keep the password at home or share it with trusted associates as protection against someone at the bank gaining access to the paper wallets and spending from them.  The foreseeable and unforeseeable use cases for password-protected private keys are numerous.
==Copyright==
This proposal is hereby placed in the public domain.
==Rationale==
:'''''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.''
:'''''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds.  I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).''
:'''''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key.  I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.''
:'''''User story:''' (EC multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate.
==Specification==
This proposal makes use of the following functions and definitions:
*'''AES256Encrypt, AES256Decrypt''': the simple form of the well-known AES block cipher without consideration for initialization vectors or block chaining.  Each of these functions takes a 256-bit key and 16 bytes of input, and deterministically yields 16 bytes of output.
*'''SHA256''', a well-known hashing algorithm that takes an arbitrary number of bytes as input and deterministically yields a 32-byte hash.
*'''scrypt''': A well-known key derivation algorithm.  It takes the following parameters: (string) password, (string) salt, (int) n, (int) r, (int) p, (int) length, and deterministically yields an array of bytes whose length is equal to the length parameter.
*'''ECMultiply''': Multiplication of an elliptic curve point by a scalar integer with respect to the [[secp256k1]] elliptic curve.
*'''G, N''': Constants defined as part of the [[secp256k1]] elliptic curve.  G is an elliptic curve point, and N is a large positive integer.
*'''[[Base58Check]]''': a method for encoding arrays of bytes using 58 alphanumeric characters commonly used in the Bitcoin ecosystem.
===Prefix===
It is proposed that the resulting Base58Check-encoded string start with a '6'.  The number '6' is intended to represent, from the perspective of the user, "a private key that needs something else to be usable" - an umbrella definition that could be understood in the future to include keys participating in multisig transactions, and was chosen with deference to the existing prefix '5' most commonly observed in [[Wallet Import Format]] which denotes an unencrypted private key.
It is proposed that the second character ought to give a hint as to what is needed as a second factor, and for an encrypted key requiring a passphrase, the uppercase letter P is proposed.
To keep the size of the encrypted key down, no initialization vectors (IVs) are used in the AES encryption.  Rather, suitable values for IV-like use are derived using scrypt from the passphrase and from using a 32-bit hash of the resulting Bitcoin address as salt.
===Proposed specification===

Object identifier prefix: 0x0142 (non-EC-multiplied) or 0x0143 (EC-multiplied).  These are constant bytes that appear at the beginning of the Base58Check-encoded record, and their presence causes the resulting string to have a predictable prefix.
How the user sees it: 58 characters always starting with '6P'
** Visual cues are present in the third character for visually identifying the EC-multiply and compress flag.
Count of payload bytes (beyond prefix): 37
** 1 byte (''flagbyte''):
*** the most significant two bits are set as follows to preserve the visibility of the compression flag in the prefix, as well as to keep the payload within the range of allowable values that keep the "6P" prefix intact.  For non-EC-multiplied keys, the bits are 11.  For EC-multiplied keys, the bits are 00.
*** the bit with value 0x20 when set indicates the key should be converted to a bitcoin address using the compressed public key format.
*** the bits with values 0x10 and 0x08 are reserved for a future specification that contemplates using multisig as a way to combine the factors such that parties in possession of the separate factors can independently sign a proposed transaction without requiring that any party possess both factors.  These bits must be 0 to comply with this version of the specification.
*** the bit with value 0x04 indicates whether a lot and sequence number are encoded into the first factor, and activates special behavior for including them in the decryption process.  This applies to EC-multiplied keys only.  Must be 0 for non-EC-multiplied keys.
*** remaining bits are reserved for future use and must all be 0 to comply with this version of the specification.
** 4 bytes: SHA256(SHA256(expected_bitcoin_address))[0...3], used both for typo checking and as salt
**16 bytes: Contents depend on whether EC multiplication is used.
**16 bytes: lasthalf: An AES-encrypted key material record (contents depend on whether EC multiplication is used)
Range in base58check encoding for non-EC-multiplied keys without compression (prefix 6PR):
** Minimum value: 6PRHv1jg1ytiE4kT2QtrUz8gEjMQghZDWg1FuxjdYDzjUkcJeGdFj9q9Vi (based on 01 42 C0 plus thirty-six 00's)
** Maximum value: 6PRWdmoT1ZursVcr5NiD14p5bHrKVGPG7yeEoEeRb8FVaqYSHnZTLEbYsU (based on 01 42 C0 plus thirty-six FF's)
Range in base58check encoding for non-EC-multiplied keys with compression (prefix 6PY):
** Minimum value: 6PYJxKpVnkXUsnZAfD2B5ZsZafJYNp4ezQQeCjs39494qUUXLnXijLx6LG (based on 01 42 E0 plus thirty-six 00's)
** Maximum value: 6PYXg5tGnLYdXDRZiAqXbeYxwDoTBNthbi3d61mqBxPpwZQezJTvQHsCnk (based on 01 42 E0 plus thirty-six FF's)
Range in base58check encoding for EC-multiplied keys without compression (prefix 6Pf):
** Minimum value: 6PfKzduKZXAFXWMtJ19Vg9cSvbFg4va6U8p2VWzSjtHQCCLk3JSBpUvfpf (based on 01 43 00 plus thirty-six 00's)
** Maximum value: 6PfYiPy6Z7BQAwEHLxxrCEHrH9kasVQ95ST1NnuEnnYAJHGsgpNPQ9dTHc (based on 01 43 00 plus thirty-six FF's)
Range in base58check encoding for EC-multiplied keys with compression (prefix 6Pn):
** Minimum value: 6PnM2wz9LHo2BEAbvoGpGjMLGXCom35XwsDQnJ7rLiRjYvCxjpLenmoBsR (based on 01 43 20 plus thirty-six 00's)
** Maximum value: 6PnZki3vKspApf2zym6Anp2jd5hiZbuaZArPfa2ePcgVf196PLGrQNyVUh (based on 01 43 20 plus thirty-six FF's)

====Encryption when EC multiply flag is not used====
Encrypting a private key without the EC multiplication offers the advantage that any known private key can be encrypted.  The party performing the encryption must know the passphrase.
Encryption steps:
Compute the Bitcoin address (ASCII), and take the first four bytes of SHA256(SHA256()) of it.  Let's call this "addresshash".
Derive a key from the passphrase using scrypt
#*Parameters: ''passphrase'' is the passphrase itself encoded in UTF-8 and normalized using Unicode Normalization Form C (NFC).  salt is ''addresshash'' from the earlier step, n=16384, r=8, p=8, length=64 (n, r, p are provisional and subject to consensus)
#*Let's split the resulting 64 bytes in half, and call them ''derivedhalf1'' and ''derivedhalf2''.
Do AES256Encrypt(block = bitcoinprivkey[0...15] xor derivedhalf1[0...15], key = derivedhalf2), call the 16-byte result ''encryptedhalf1''
Do AES256Encrypt(block = bitcoinprivkey[16...31] xor derivedhalf1[16...31], key = derivedhalf2), call the 16-byte result ''encryptedhalf2''
The encrypted private key is the Base58Check-encoded concatenation of the following, which totals 39 bytes without Base58 checksum:

0x01 0x42 + ''flagbyte'' + ''salt'' + ''encryptedhalf1'' + ''encryptedhalf2''

Decryption steps:
Collect encrypted private key and passphrase from user.
Derive ''derivedhalf1'' and ''derivedhalf2'' by passing the passphrase and ''addresshash'' into scrypt function.
Decrypt ''encryptedhalf1'' and ''encryptedhalf2'' using AES256Decrypt, merge them to form the encrypted private key.
Convert that private key into a Bitcoin address, honoring the compression preference specified in ''flagbyte'' of the encrypted key record.
Hash the Bitcoin address, and verify that ''addresshash'' from the encrypted private key record matches the hash.  If not, report that the passphrase entry was incorrect.
====Encryption when EC multiply mode is used====
Encrypting a private key with EC multiplication offers the ability for someone to generate encrypted keys knowing only an EC point derived from the original passphrase and some salt generated by the passphrase's owner, and without knowing the passphrase itself.  Only the person who knows the original passphrase can decrypt the private key.  A code known as an ''intermediate code'' conveys the information needed to generate such a key without knowledge of the passphrase.
This methodology does not offer the ability to encrypt a known private key - this means that the process of creating encrypted keys is also the process of generating new addresses.  On the other hand, this serves a security benefit for someone possessing an address generated this way: if the address can be recreated by decrypting its private key with a passphrase, and it's a strong passphrase one can be certain only he knows himself, then he can safely conclude that nobody could know the private key to that address.
The person who knows the passphrase and who is the intended beneficiary of the private keys is called the ''owner''.  He will generate one or more "intermediate codes", which are the first factor of a two-factor redemption system, and will give them to someone else we'll call ''printer'', who generates a key pair with an intermediate code can know the address and encrypted private key, but cannot decrypt the private key without the original passphrase.
An intermediate code should, but is not required to, embed a printable "lot" and "sequence" number for the benefit of the user.  The proposal forces these lot and sequence numbers to be included in any valid private keys generated from them.  An owner who has requested multiple private keys to be generated for him will be advised by applications to ensure that each private key has a unique lot and sequence number consistent with the intermediate codes he generated.  These mainly help protect ''owner'' from potential mistakes and/or attacks that could be made by ''printer''.
The "lot" and "sequence" number are combined into a single 32 bit number.  20 bits are used for the lot number and 12 bits are used for the sequence number, such that the lot number can be any decimal number between 0 and 1048575, and the sequence number can be any decimal number between 0 and 4095.  For programs that generate batches of intermediate codes for an ''owner'', it is recommended that lot numbers be chosen at random within the range<PHONE_NUMBER>99 and that sequence numbers are assigned starting with 1.
Steps performed by ''owner'' to generate a single intermediate code, if lot and sequence numbers are being included:
Generate 4 random bytes, call them ''ownersalt''.
Encode the lot and sequence numbers as a 4 byte quantity (big-endian): lotnumber * 4096 + sequencenumber.  Call these four bytes ''lotsequence''.
Concatenate ''ownersalt'' + ''lotsequence'' and call this ''ownerentropy''.
Derive a key from the passphrase using scrypt
#* Parameters: ''passphrase'' is the passphrase itself encoded in UTF-8 and normalized using Unicode Normalization Form C (NFC).  salt is ''ownersalt''. n=16384, r=8, p=8, length=32.
#* Call the resulting 32 bytes ''prefactor''.
#* Take SHA256(SHA256(''prefactor'' + ''ownerentropy'')) and call this ''passfactor''. The "+" operator is concatenation.
Compute the elliptic curve point G * ''passfactor'', and convert the result to compressed notation (33 bytes).  Call this ''passpoint''.  Compressed notation is used for this purpose regardless of whether the intent is to create Bitcoin addresses with or without compressed public keys.
Convey ''ownersalt'' and ''passpoint'' to the party generating the keys, along with a checksum to ensure integrity.
#* The following Base58Check-encoded format is recommended for this purpose: magic bytes "2C E9 B3 E1 FF 39 E2 51" followed by ''ownerentropy'', and then ''passpoint''.  The resulting string will start with the word "passphrase" due to the constant bytes, will be 72 characters in length, and encodes 49 bytes (8 bytes constant + 8 bytes ''ownerentropy'' + 33 bytes ''passpoint'').  The checksum is handled in the Base58Check encoding.  The resulting string is called ''intermediate_passphrase_string''.
If lot and sequence numbers are not being included, then follow the same procedure with the following changes:

''ownersalt'' is 8 random bytes instead of 4, and ''lotsequence'' is omitted.  ''ownerentropy'' becomes an alias for ''ownersalt''.
The SHA256 conversion of ''prefactor'' to ''passfactor'' is omitted.  Instead, the output of scrypt is used directly as ''passfactor''.
The magic bytes are "2C E9 B3 E1 FF 39 E2 53" instead (the last byte is 0x53 instead of 0x51).

Steps to create new encrypted private keys given ''intermediate_passphrase_string'' from ''owner'' (so we have ''ownerentropy'', and ''passpoint'', but we do not have ''passfactor'' or the passphrase):
Set ''flagbyte''.
#* Turn on bit 0x20 if the Bitcoin address will be formed by hashing the compressed public key (optional, saves space, but many Bitcoin implementations aren't compatible with it)
#* Turn on bit 0x04 if ''ownerentropy'' contains a value for ''lotsequence''.  (While it has no effect on the keypair generation process, the decryption process needs this flag to know how to process ''ownerentropy'')
Generate 24 random bytes, call this ''seedb''.  Take SHA256(SHA256(''seedb'')) to yield 32 bytes, call this ''factorb''.
ECMultiply ''passpoint'' by ''factorb''.  Use the resulting EC point as a public key and hash it into a Bitcoin address using either compressed or uncompressed public key methodology (specify which methodology is used inside ''flagbyte'').  This is the generated Bitcoin address, call it ''generatedaddress''.
Take the first four bytes of SHA256(SHA256(''generatedaddress'')) and call it ''addresshash''.
Now we will encrypt ''seedb''.  Derive a second key from ''passpoint'' using scrypt
#*Parameters: ''passphrase'' is ''passpoint'' provided from the first party (expressed in binary as 33 bytes).  ''salt'' is ''addresshash'' + ''ownerentropy'', n=1024, r=1, p=1, length=64.  The "+" operator is concatenation.
#*Split the result into two 32-byte halves and call them ''derivedhalf1'' and ''derivedhalf2''.
Do AES256Encrypt(block = (seedb[0...15] xor derivedhalf1[0...15]), key = derivedhalf2), call the 16-byte result ''encryptedpart1''
Do AES256Encrypt(block = ((encryptedpart1[8...15] + seedb[16...23]) xor derivedhalf1[16...31]), key = derivedhalf2), call the 16-byte result ''encryptedpart2''.  The "+" operator is concatenation.
The encrypted private key is the Base58Check-encoded concatenation of the following, which totals 39 bytes without Base58 checksum:

0x01 0x43 + ''flagbyte'' + ''addresshash'' + ''ownerentropy'' + ''encryptedpart1''[0...7] + ''encryptedpart2''

=====Confirmation code=====
The party generating the Bitcoin address has the option to return a ''confirmation code'' back to ''owner'' which allows ''owner'' to independently verify that he has been given a Bitcoin address that actually depends on his passphrase, and to confirm the lot and sequence numbers (if applicable).  This protects ''owner'' from being given a Bitcoin address by the second party that is unrelated to the key derivation and possibly spendable by the second party.  If a Bitcoin address given to ''owner'' can be successfully regenerated through the confirmation process, ''owner'' can be reasonably assured that any spending without the passphrase is infeasible.  This confirmation code is 75 characters starting with "cfrm38".
To generate it, we need ''flagbyte'', ''ownerentropy'', ''factorb'', ''derivedhalf1'' and ''derivedhalf2'' from the original encryption operation.
ECMultiply ''factorb'' by G, call the result ''pointb''.  The result is 33 bytes.
The first byte is 0x02 or 0x03.  XOR it by (derivedhalf2[31] & 0x01), call the resulting byte ''pointbprefix''.
Do AES256Encrypt(block = (pointb[1...16] xor derivedhalf1[0...15]), key = derivedhalf2) and call the result ''pointbx1''.
Do AES256Encrypt(block = (pointb[17...32] xor derivedhalf1[16...31]), key = derivedhalf2) and call the result ''pointbx2''.
Concatenate ''pointbprefix'' + ''pointbx1'' + ''pointbx2'' (total 33 bytes) and call the result ''encryptedpointb''.
The result is a Base58Check-encoded concatenation of the following:

0x64 0x3B 0xF6 0xA8 0x9A + ''flagbyte'' + ''addresshash'' + ''ownerentropy'' + ''encryptedpointb''

A confirmation tool, given a passphrase and a confirmation code, can recalculate the address, verify the address hash, and then assert the following: "It is confirmed that Bitcoin address ''address'' depends on this passphrase".  If applicable: "The lot number is ''lotnumber'' and the sequence number is ''sequencenumber''."
To recalculate the address:
Derive ''passfactor'' using scrypt with ''ownerentropy'' and the user's passphrase and use it to recompute ''passpoint''
Derive decryption key for ''pointb'' using scrypt with ''passpoint'', ''addresshash'', and ''ownerentropy''
Decrypt ''encryptedpointb'' to yield ''pointb''
ECMultiply ''pointb'' by ''passfactor''. Use the resulting EC point as a public key and hash it into ''address'' using either compressed or uncompressed public key methodology as specifid in ''flagbyte''.
=====Decryption=====
Collect encrypted private key and passphrase from user.
Derive ''passfactor'' using scrypt with ''ownersalt'' and the user's passphrase and use it to recompute ''passpoint''
Derive decryption key for ''seedb'' using scrypt with ''passpoint'', ''addresshash'', and ''ownerentropy''
Decrypt ''encryptedpart2'' using AES256Decrypt to yield the last 8 bytes of ''seedb'' and the last 8 bytes of ''encryptedpart1''.
Decrypt ''encryptedpart1'' to yield the remainder of ''seedb''.
Use ''seedb'' to compute ''factorb''.
Multiply ''passfactor'' by ''factorb'' mod N to yield the private key associated with ''generatedaddress''.
Convert that private key into a Bitcoin address, honoring the compression preference specified in the encrypted key.
Hash the Bitcoin address, and verify that ''addresshash'' from the encrypted private key record matches the hash.  If not, report that the passphrase entry was incorrect.
==Backwards compatibility==
Backwards compatibility is minimally applicable since this is a new standard that at most extends [[Wallet Import Format]].  It is assumed that an entry point for private key data may also accept existing formats of private keys (such as hexadecimal and [[Wallet Import Format]]); this draft uses a key format that cannot be mistaken for any existing one and preserves auto-detection capabilities.
==Suggestions for implementers of proposal with alt-chains==
If this proposal is accepted into alt-chains, it is requested that the unused flag bytes not be used for denoting that the key belongs to an alt-chain.
Alt-chain implementers should exploit the address hash for this purpose.  Since each operation in this proposal involves hashing a text representation of a coin address which (for Bitcoin) includes the leading '1', an alt-chain can easily be denoted simply by using the alt-chain's preferred format for representing an address.  Alt-chain implementers may also change the prefix such that encrypted addresses do not start with "6P".
==Discussion item: scrypt parameters==
This proposal leaves the scrypt parameters up in the air.  The following items are proposed for consideration:
The main goal of scrypt is to reduce the feasibility of brute force attacks.  It must be assumed that an attacker will be able to use an efficient implementation of scrypt.  The parameters should force a highly efficient implementation of scrypt to wait a decent amount of time to slow attacks.
On the other hand, an unavoidably likely place where scrypt will be implemented is using slow interpreted languages such as javascript.  What might take milliseconds on an efficient scrypt implementation may take seconds in javascript.
It is believed, however, that someone using a javascript implementation is probably dealing with codes by hand, one at a time, rather than generating or processing large batches of codes.  Thus, a wait time of several seconds is acceptable to a user.
A private key redemption process that forces a server to consume several seconds of CPU time would discourage implementation by the server owner, because they would be opening up a denial of service avenue by inviting users to make numerous attempts to invoke the redemption process.  However, it's also feasible for the server owner to implement his redemption process in such a way that the decryption is done by the user's browser, offloading the task from his own server (and providing another reason why the chosen scrypt parameters should be tolerant of javascript-based decryptors).
The preliminary values of 16384, 8, and 8 are hoped to offer the following properties:

Encryption/decryption in javascript requiring several seconds per operation
Use of the parallelization parameter provides a modest opportunity for speedups in environments where concurrent threading is available - such environments would be selected for processes that must handle bulk quantities of encryption/decryption operations.  Estimated time for an operation is in the tens or hundreds of milliseconds.

==Reference implementation==
Added to alpha version of Casascius Bitcoin Address Utility for Windows available at:

via https: https://casascius.com/btcaddress-alpha.zip
at github: https://github.com/casascius/Bitcoin-Address-Utility

Click "Tools" then "PPEC Keygen" (provisional name)
==Test vectors==
===No compression, no EC multiply===
Test 1:
*Passphrase: TestingOneTwoThree
*Encrypted: 6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg
*Unencrypted (WIF): 5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR
*Unencrypted (hex): CBF4B9F70470856BB4F40F80B87EDB90865997FFEE6DF315AB166D713AF433A5
Test 2:
*Passphrase: Satoshi
*Encrypted: 6PRNFFkZc2NZ6dJqFfhRoFNMR9Lnyj7dYGrzdgXXVMXcxoKTePPX1dWByq
*Unencrypted (WIF): 5HtasZ6ofTHP6HCwTqTkLDuLQisYPah7aUnSKfC7h4hMUVw2gi5
*Unencrypted (hex): 09C2686880095B1A4C249EE3AC4EEA8A014F11E6F986D0B5025AC1F39AFBD9AE
Test 3:
*Passphrase ϓ␀𐐀💩 (\u03D2\u0301\u0000\U00010400\U0001F4A9; [http://codepoints.net/U+03D2 GREEK UPSILON WITH HOOK], [http://codepoints.net/U+0301 COMBINING ACUTE ACCENT], [http://codepoints.net/U+0000 NULL], [http://codepoints.net/U+10400 DESERET CAPITAL LETTER LONG I], [http://codepoints.net/U+1F4A9 PILE OF POO])
*Encrypted key: 6PRW5o9FLp4gJDDVqJQKJFTpMvdsSGJxMYHtHaQBF3ooa8mwD69bapcDQn
*Bitcoin Address: 16ktGzmfrurhbhi6JGqsMWf7TyqK9HNAeF
*Unencrypted private key (WIF): 5Jajm8eQ22H3pGWLEVCXyvND8dQZhiQhoLJNKjYXk9roUFTMSZ4

''Note:'' The non-standard UTF-8 characters in this passphrase should be NFC normalized to result in a passphrase of 0xcf9300f0909080f09f92a9 before further processing

===Compression, no EC multiply===
Test 1:
*Passphrase: TestingOneTwoThree
*Encrypted: 6PYNKZ1EAgYgmQfmNVamxyXVWHzK5s6DGhwP4J5o44cvXdoY7sRzhtpUeo
*Unencrypted (WIF): L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP
*Unencrypted (hex): CBF4B9F70470856BB4F40F80B87EDB90865997FFEE6DF315AB166D713AF433A5
Test 2:
*Passphrase: Satoshi
*Encrypted: 6PYLtMnXvfG3oJde97zRyLYFZCYizPU5T3LwgdYJz1fRhh16bU7u6PPmY7
*Unencrypted (WIF): KwYgW8gcxj1JWJXhPSu4Fqwzfhp5Yfi42mdYmMa4XqK7NJxXUSK7
*Unencrypted (hex): 09C2686880095B1A4C249EE3AC4EEA8A014F11E6F986D0B5025AC1F39AFBD9AE
===EC multiply, no compression, no lot/sequence numbers===
Test 1:
*Passphrase: TestingOneTwoThree
*Passphrase code: passphrasepxFy57B9v8HtUsszJYKReoNDV6VHjUSGt8EVJmux9n1J3Ltf1gRxyDGXqnf9qm
*Encrypted key: 6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX
*Bitcoin address: 1PE6TQi6HTVNz5DLwB1LcpMBALubfuN2z2
*Unencrypted private key (WIF): 5K4caxezwjGCGfnoPTZ8tMcJBLB7Jvyjv4xxeacadhq8nLisLR2
*Unencrypted private key (hex): A43A940577F4E97F5C4D39EB14FF083A98187C64EA7C99EF7CE460833959A519
Test 2:
*Passphrase: Satoshi
*Passphrase code: passphraseoRDGAXTWzbp72eVbtUDdn1rwpgPUGjNZEc6CGBo8i5EC1FPW8wcnLdq4ThKzAS
*Encrypted key: 6PfLGnQs6VZnrNpmVKfjotbnQuaJK4KZoPFrAjx1JMJUa1Ft8gnf5WxfKd
*Bitcoin address: 1CqzrtZC6mXSAhoxtFwVjz8LtwLJjDYU3V
*Unencrypted private key (WIF): 5KJ51SgxWaAYR13zd9ReMhJpwrcX47xTJh2D3fGPG9CM8vkv5sH
*Unencrypted private key (hex): C2C8036DF268F498099350718C4A3EF3984D2BE84618C2650F5171DCC5EB660A
===EC multiply, no compression, lot/sequence numbers===
Test 1:
*Passphrase: MOLON LABE
*Passphrase code: passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX
*Encrypted key: 6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j
*Bitcoin address: 1Jscj8ALrYu2y9TD8NrpvDBugPedmbj4Yh
*Unencrypted private key (WIF): 5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8
*Unencrypted private key (hex): 44EA95AFBF138356A05EA32110DFD627232D0F2991AD221187BE356F19FA8190
*Confirmation code: cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD
*Lot/Sequence: 263183/1
Test 2:
*Passphrase (all letters are Greek - test UTF-8 compatibility with this): ΜΟΛΩΝ ΛΑΒΕ
*Passphrase code: passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK
*Encrypted private key: 6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH
*Bitcoin address: 1Lurmih3KruL4xDB5FmHof38yawNtP9oGf
*Unencrypted private key (WIF): 5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D
*Unencrypted private key (hex): CA2759AA4ADB0F96C414F36ABEB8DB59342985BE9FA50FAAC228C8E7D90E3006
*Confirmation code: cfrm38V8G4qq2ywYEFfWLD5Cc6msj9UwsG2Mj4Z6QdGJAFQpdatZLavkgRd1i4iBMdRngDqDs51
*Lot/Sequence: 806938/1

@uvhw

`
BIP: 38
Title: Passphrase-protected private key
Authors: Mike Caldwell
Aaron Voisine<EMAIL_ADDRESS>Status: Draft (Some confusion applies: The announcements for this never made it to the list, so it hasn't had public discussion)
Type: Standards Track
Created: 2012-11-20
==Abstract== A method is proposed for encrypting and encoding a passphrase-protected Bitcoin private key record in the form of a 58-character Base58Check-encoded printable string. Encrypted private key records are intended for use on paper wallets and physical Bitcoins. Each record string contains all the information needed to reconstitute the private key except for a passphrase, and the methodology uses salting and ''scrypt'' to resist brute-force attacks.
The method provides two encoding methodologies - one permitting any known private key to be encrypted with any passphrase, and another permitting a shared private key generation scheme where the party generating the final key string and its associated Bitcoin address (such as a physical bitcoin manufacturer) knows only a string derived from the original passphrase, and where the original passphrase is needed in order to actually redeem funds sent to the associated Bitcoin address.
A 32-bit hash of the resulting Bitcoin address is encoded in plaintext within each encrypted key, so it can be correlated to a Bitcoin address with reasonable probability by someone not knowing the passphrase. The complete Bitcoin address can be derived through successful decryption of the key record.
==Motivation== The motivation to make this proposal stems from observations of the way physical bitcoins and paper wallets are used.
An issuer of physical bitcoins must be trustworthy and trusted. Even if trustworthy, users are rightful to be skeptical about a third party with theoretical access to take their funds. A physical bitcoin that cannot be compromised by its issuer is always more intrinsically valuable than one that can.
A two-factor physical bitcoin solution is highly useful to individuals and organizations wishing to securely own bitcoins without any risk of electronic theft and without the responsibility of climbing the technological learning curve necessary to produce such an environment themselves. Two-factor physical bitcoins allow a secure storage solution to be put in a box and sold on the open market, greatly enlarging the number of people who are able to securely store bitcoins.
Existing methodologies for creating two-factor physical bitcoins are limited and cumbersome. At the time of this proposal, a user could create their own private key, submit the public key to the physical bitcoin issuer, and then receive a physical bitcoin that must be kept together with some sort of record of the user-generated private key, and finally, must be redeemed through a tool. The fact that the physical bitcoin must be kept together with a user-produced private key negates much of the benefit of the physical bitcoin - the user may as well just print and maintain a private key.
A standardized password-protected private key format makes acquiring and redeeming two-factor physical bitcoins simpler for the user. Instead of maintaining a private key that cannot be memorized, the user may choose a passphrase of their choice. The passphrase may be much shorter than the length of a typical private key, short enough that they could use a label or engraver to permanently commit their passphrase to their physical Bitcoin piece once they have received it. By adopting a standard way to encrypt a private key, we maximize the possibility that they'll be able to redeem their funds in the venue of their choice, rather than relying on an executable redemption tool they may not wish to download.
Password and passphrase-protected private keys enable new practical use cases for sending bitcoins from person to person. Someone wanting to send bitcoins through postal mail could send a password-protected paper wallet and give the recipient the passphrase over the phone or e-mail, making the transfer safe from interception of either channel. A user of paper wallets or Bitcoin banknote-style vouchers ("cash") could carry funded encrypted private keys while leaving a copy at home as an element of protection against accidental loss or theft. A user of paper wallets who leaves bitcoins in a bank vault or safety deposit box could keep the password at home or share it with trusted associates as protection against someone at the bank gaining access to the paper wallets and spending from them. The foreseeable and unforeseeable use cases for password-protected private keys are numerous.
==Copyright== This proposal is hereby placed in the public domain.
==Rationale== :'''''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.'' :'''''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds. I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).'' :'''''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key. I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.'' :'''''User story:''' (EC multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate.
==Specification== This proposal makes use of the following functions and definitions:
*'''AES256Encrypt, AES256Decrypt''': the simple form of the well-known AES block cipher without consideration for initialization vectors or block chaining. Each of these functions takes a 256-bit key and 16 bytes of input, and deterministically yields 16 bytes of output. *'''SHA256''', a well-known hashing algorithm that takes an arbitrary number of bytes as input and deterministically yields a 32-byte hash. *'''scrypt''': A well-known key derivation algorithm. It takes the following parameters: (string) password, (string) salt, (int) n, (int) r, (int) p, (int) length, and deterministically yields an array of bytes whose length is equal to the length parameter. *'''ECMultiply''': Multiplication of an elliptic curve point by a scalar integer with respect to the [[secp256k1]] elliptic curve. *'''G, N''': Constants defined as part of the [[secp256k1]] elliptic curve. G is an elliptic curve point, and N is a large positive integer. *'''[[Base58Check]]''': a method for encoding arrays of bytes using 58 alphanumeric characters commonly used in the Bitcoin ecosystem.
===Prefix=== It is proposed that the resulting Base58Check-encoded string start with a '6'. The number '6' is intended to represent, from the perspective of the user, "a private key that needs something else to be usable" - an umbrella definition that could be understood in the future to include keys participating in multisig transactions, and was chosen with deference to the existing prefix '5' most commonly observed in [[Wallet Import Format]] which denotes an unencrypted private key.
It is proposed that the second character ought to give a hint as to what is needed as a second factor, and for an encrypted key requiring a passphrase, the uppercase letter P is proposed.
To keep the size of the encrypted key down, no initialization vectors (IVs) are used in the AES encryption. Rather, suitable values for IV-like use are derived using scrypt from the passphrase and from using a 32-bit hash of the resulting Bitcoin address as salt.
===Proposed specification===

Object identifier prefix: 0x0142 (non-EC-multiplied) or 0x0143 (EC-multiplied).  These are constant bytes that appear at the beginning of the Base58Check-encoded record, and their presence causes the resulting string to have a predictable prefix.
How the user sees it: 58 characters always starting with '6P'
** Visual cues are present in the third character for visually identifying the EC-multiply and compress flag.
Count of payload bytes (beyond prefix): 37
** 1 byte (''flagbyte''):
*** the most significant two bits are set as follows to preserve the visibility of the compression flag in the prefix, as well as to keep the payload within the range of allowable values that keep the "6P" prefix intact.  For non-EC-multiplied keys, the bits are 11.  For EC-multiplied keys, the bits are 00.
*** the bit with value 0x20 when set indicates the key should be converted to a bitcoin address using the compressed public key format.
*** the bits with values 0x10 and 0x08 are reserved for a future specification that contemplates using multisig as a way to combine the factors such that parties in possession of the separate factors can independently sign a proposed transaction without requiring that any party possess both factors.  These bits must be 0 to comply with this version of the specification.
*** the bit with value 0x04 indicates whether a lot and sequence number are encoded into the first factor, and activates special behavior for including them in the decryption process.  This applies to EC-multiplied keys only.  Must be 0 for non-EC-multiplied keys.
*** remaining bits are reserved for future use and must all be 0 to comply with this version of the specification.
** 4 bytes: SHA256(SHA256(expected_bitcoin_address))[0...3], used both for typo checking and as salt
**16 bytes: Contents depend on whether EC multiplication is used.
**16 bytes: lasthalf: An AES-encrypted key material record (contents depend on whether EC multiplication is used)
Range in base58check encoding for non-EC-multiplied keys without compression (prefix 6PR):
** Minimum value: 6PRHv1jg1ytiE4kT2QtrUz8gEjMQghZDWg1FuxjdYDzjUkcJeGdFj9q9Vi (based on 01 42 C0 plus thirty-six 00's)
** Maximum value: 6PRWdmoT1ZursVcr5NiD14p5bHrKVGPG7yeEoEeRb8FVaqYSHnZTLEbYsU (based on 01 42 C0 plus thirty-six FF's)
Range in base58check encoding for non-EC-multiplied keys with compression (prefix 6PY):
** Minimum value: 6PYJxKpVnkXUsnZAfD2B5ZsZafJYNp4ezQQeCjs39494qUUXLnXijLx6LG (based on 01 42 E0 plus thirty-six 00's)
** Maximum value: 6PYXg5tGnLYdXDRZiAqXbeYxwDoTBNthbi3d61mqBxPpwZQezJTvQHsCnk (based on 01 42 E0 plus thirty-six FF's)
Range in base58check encoding for EC-multiplied keys without compression (prefix 6Pf):
** Minimum value: 6PfKzduKZXAFXWMtJ19Vg9cSvbFg4va6U8p2VWzSjtHQCCLk3JSBpUvfpf (based on 01 43 00 plus thirty-six 00's)
** Maximum value: 6PfYiPy6Z7BQAwEHLxxrCEHrH9kasVQ95ST1NnuEnnYAJHGsgpNPQ9dTHc (based on 01 43 00 plus thirty-six FF's)
Range in base58check encoding for EC-multiplied keys with compression (prefix 6Pn):
** Minimum value: 6PnM2wz9LHo2BEAbvoGpGjMLGXCom35XwsDQnJ7rLiRjYvCxjpLenmoBsR (based on 01 43 20 plus thirty-six 00's)
** Maximum value: 6PnZki3vKspApf2zym6Anp2jd5hiZbuaZArPfa2ePcgVf196PLGrQNyVUh (based on 01 43 20 plus thirty-six FF's)

====Encryption when EC multiply flag is not used==== Encrypting a private key without the EC multiplication offers the advantage that any known private key can be encrypted. The party performing the encryption must know the passphrase.
Encryption steps:
Compute the Bitcoin address (ASCII), and take the first four bytes of SHA256(SHA256()) of it. Let's call this "addresshash".
Derive a key from the passphrase using scrypt
#*Parameters: ''passphrase'' is the passphrase itself encoded in UTF-8 and normalized using Unicode Normalization Form C (NFC). salt is ''addresshash'' from the earlier step, n=16384, r=8, p=8, length=64 (n, r, p are provisional and subject to consensus) #*Let's split the resulting 64 bytes in half, and call them ''derivedhalf1'' and ''derivedhalf2''.
Do AES256Encrypt(block = bitcoinprivkey[0...15] xor derivedhalf1[0...15], key = derivedhalf2), call the 16-byte result ''encryptedhalf1''
Do AES256Encrypt(block = bitcoinprivkey[16...31] xor derivedhalf1[16...31], key = derivedhalf2), call the 16-byte result ''encryptedhalf2''
The encrypted private key is the Base58Check-encoded concatenation of the following, which totals 39 bytes without Base58 checksum:

0x01 0x42 + ''flagbyte'' + ''salt'' + ''encryptedhalf1'' + ''encryptedhalf2''

Decryption steps:
Collect encrypted private key and passphrase from user.
Derive ''derivedhalf1'' and ''derivedhalf2'' by passing the passphrase and ''addresshash'' into scrypt function.
Decrypt ''encryptedhalf1'' and ''encryptedhalf2'' using AES256Decrypt, merge them to form the encrypted private key.
Convert that private key into a Bitcoin address, honoring the compression preference specified in ''flagbyte'' of the encrypted key record.
Hash the Bitcoin address, and verify that ''addresshash'' from the encrypted private key record matches the hash. If not, report that the passphrase entry was incorrect.
====Encryption when EC multiply mode is used==== Encrypting a private key with EC multiplication offers the ability for someone to generate encrypted keys knowing only an EC point derived from the original passphrase and some salt generated by the passphrase's owner, and without knowing the passphrase itself. Only the person who knows the original passphrase can decrypt the private key. A code known as an ''intermediate code'' conveys the information needed to generate such a key without knowledge of the passphrase.
This methodology does not offer the ability to encrypt a known private key - this means that the process of creating encrypted keys is also the process of generating new addresses. On the other hand, this serves a security benefit for someone possessing an address generated this way: if the address can be recreated by decrypting its private key with a passphrase, and it's a strong passphrase one can be certain only he knows himself, then he can safely conclude that nobody could know the private key to that address.
The person who knows the passphrase and who is the intended beneficiary of the private keys is called the ''owner''. He will generate one or more "intermediate codes", which are the first factor of a two-factor redemption system, and will give them to someone else we'll call ''printer'', who generates a key pair with an intermediate code can know the address and encrypted private key, but cannot decrypt the private key without the original passphrase.
An intermediate code should, but is not required to, embed a printable "lot" and "sequence" number for the benefit of the user. The proposal forces these lot and sequence numbers to be included in any valid private keys generated from them. An owner who has requested multiple private keys to be generated for him will be advised by applications to ensure that each private key has a unique lot and sequence number consistent with the intermediate codes he generated. These mainly help protect ''owner'' from potential mistakes and/or attacks that could be made by ''printer''.
The "lot" and "sequence" number are combined into a single 32 bit number. 20 bits are used for the lot number and 12 bits are used for the sequence number, such that the lot number can be any decimal number between 0 and 1048575, and the sequence number can be any decimal number between 0 and 4095. For programs that generate batches of intermediate codes for an ''owner'', it is recommended that lot numbers be chosen at random within the range<PHONE_NUMBER>99 and that sequence numbers are assigned starting with 1.
Steps performed by ''owner'' to generate a single intermediate code, if lot and sequence numbers are being included:
Generate 4 random bytes, call them ''ownersalt''.
Encode the lot and sequence numbers as a 4 byte quantity (big-endian): lotnumber * 4096 + sequencenumber. Call these four bytes ''lotsequence''.
Concatenate ''ownersalt'' + ''lotsequence'' and call this ''ownerentropy''.
Derive a key from the passphrase using scrypt
#* Parameters: ''passphrase'' is the passphrase itself encoded in UTF-8 and normalized using Unicode Normalization Form C (NFC). salt is ''ownersalt''. n=16384, r=8, p=8, length=32. #* Call the resulting 32 bytes ''prefactor''. #* Take SHA256(SHA256(''prefactor'' + ''ownerentropy'')) and call this ''passfactor''. The "+" operator is concatenation.
Compute the elliptic curve point G * ''passfactor'', and convert the result to compressed notation (33 bytes). Call this ''passpoint''. Compressed notation is used for this purpose regardless of whether the intent is to create Bitcoin addresses with or without compressed public keys.
Convey ''ownersalt'' and ''passpoint'' to the party generating the keys, along with a checksum to ensure integrity.
#* The following Base58Check-encoded format is recommended for this purpose: magic bytes "2C E9 B3 E1 FF 39 E2 51" followed by ''ownerentropy'', and then ''passpoint''. The resulting string will start with the word "passphrase" due to the constant bytes, will be 72 characters in length, and encodes 49 bytes (8 bytes constant + 8 bytes ''ownerentropy'' + 33 bytes ''passpoint''). The checksum is handled in the Base58Check encoding. The resulting string is called ''intermediate_passphrase_string''.
If lot and sequence numbers are not being included, then follow the same procedure with the following changes:

''ownersalt'' is 8 random bytes instead of 4, and ''lotsequence'' is omitted.  ''ownerentropy'' becomes an alias for ''ownersalt''.
The SHA256 conversion of ''prefactor'' to ''passfactor'' is omitted.  Instead, the output of scrypt is used directly as ''passfactor''.
The magic bytes are "2C E9 B3 E1 FF 39 E2 53" instead (the last byte is 0x53 instead of 0x51).

Steps to create new encrypted private keys given ''intermediate_passphrase_string'' from ''owner'' (so we have ''ownerentropy'', and ''passpoint'', but we do not have ''passfactor'' or the passphrase):
Set ''flagbyte''.
#* Turn on bit 0x20 if the Bitcoin address will be formed by hashing the compressed public key (optional, saves space, but many Bitcoin implementations aren't compatible with it) #* Turn on bit 0x04 if ''ownerentropy'' contains a value for ''lotsequence''. (While it has no effect on the keypair generation process, the decryption process needs this flag to know how to process ''ownerentropy'')
Generate 24 random bytes, call this ''seedb''. Take SHA256(SHA256(''seedb'')) to yield 32 bytes, call this ''factorb''.
ECMultiply ''passpoint'' by ''factorb''. Use the resulting EC point as a public key and hash it into a Bitcoin address using either compressed or uncompressed public key methodology (specify which methodology is used inside ''flagbyte''). This is the generated Bitcoin address, call it ''generatedaddress''.
Take the first four bytes of SHA256(SHA256(''generatedaddress'')) and call it ''addresshash''.
Now we will encrypt ''seedb''. Derive a second key from ''passpoint'' using scrypt
#*Parameters: ''passphrase'' is ''passpoint'' provided from the first party (expressed in binary as 33 bytes). ''salt'' is ''addresshash'' + ''ownerentropy'', n=1024, r=1, p=1, length=64. The "+" operator is concatenation. #*Split the result into two 32-byte halves and call them ''derivedhalf1'' and ''derivedhalf2''.
Do AES256Encrypt(block = (seedb[0...15] xor derivedhalf1[0...15]), key = derivedhalf2), call the 16-byte result ''encryptedpart1''
Do AES256Encrypt(block = ((encryptedpart1[8...15] + seedb[16...23]) xor derivedhalf1[16...31]), key = derivedhalf2), call the 16-byte result ''encryptedpart2''. The "+" operator is concatenation.
The encrypted private key is the Base58Check-encoded concatenation of the following, which totals 39 bytes without Base58 checksum:

0x01 0x43 + ''flagbyte'' + ''addresshash'' + ''ownerentropy'' + ''encryptedpart1''[0...7] + ''encryptedpart2''

=====Confirmation code===== The party generating the Bitcoin address has the option to return a ''confirmation code'' back to ''owner'' which allows ''owner'' to independently verify that he has been given a Bitcoin address that actually depends on his passphrase, and to confirm the lot and sequence numbers (if applicable). This protects ''owner'' from being given a Bitcoin address by the second party that is unrelated to the key derivation and possibly spendable by the second party. If a Bitcoin address given to ''owner'' can be successfully regenerated through the confirmation process, ''owner'' can be reasonably assured that any spending without the passphrase is infeasible. This confirmation code is 75 characters starting with "cfrm38".
To generate it, we need ''flagbyte'', ''ownerentropy'', ''factorb'', ''derivedhalf1'' and ''derivedhalf2'' from the original encryption operation.
ECMultiply ''factorb'' by G, call the result ''pointb''. The result is 33 bytes.
The first byte is 0x02 or 0x03. XOR it by (derivedhalf2[31] & 0x01), call the resulting byte ''pointbprefix''.
Do AES256Encrypt(block = (pointb[1...16] xor derivedhalf1[0...15]), key = derivedhalf2) and call the result ''pointbx1''.
Do AES256Encrypt(block = (pointb[17...32] xor derivedhalf1[16...31]), key = derivedhalf2) and call the result ''pointbx2''.
Concatenate ''pointbprefix'' + ''pointbx1'' + ''pointbx2'' (total 33 bytes) and call the result ''encryptedpointb''.
The result is a Base58Check-encoded concatenation of the following:

0x64 0x3B 0xF6 0xA8 0x9A + ''flagbyte'' + ''addresshash'' + ''ownerentropy'' + ''encryptedpointb''

A confirmation tool, given a passphrase and a confirmation code, can recalculate the address, verify the address hash, and then assert the following: "It is confirmed that Bitcoin address ''address'' depends on this passphrase". If applicable: "The lot number is ''lotnumber'' and the sequence number is ''sequencenumber''."
To recalculate the address:
Derive ''passfactor'' using scrypt with ''ownerentropy'' and the user's passphrase and use it to recompute ''passpoint''
Derive decryption key for ''pointb'' using scrypt with ''passpoint'', ''addresshash'', and ''ownerentropy''
Decrypt ''encryptedpointb'' to yield ''pointb''
ECMultiply ''pointb'' by ''passfactor''. Use the resulting EC point as a public key and hash it into ''address'' using either compressed or uncompressed public key methodology as specifid in ''flagbyte''.
=====Decryption=====
Collect encrypted private key and passphrase from user.
Derive ''passfactor'' using scrypt with ''ownersalt'' and the user's passphrase and use it to recompute ''passpoint''
Derive decryption key for ''seedb'' using scrypt with ''passpoint'', ''addresshash'', and ''ownerentropy''
Decrypt ''encryptedpart2'' using AES256Decrypt to yield the last 8 bytes of ''seedb'' and the last 8 bytes of ''encryptedpart1''.
Decrypt ''encryptedpart1'' to yield the remainder of ''seedb''.
Use ''seedb'' to compute ''factorb''.
Multiply ''passfactor'' by ''factorb'' mod N to yield the private key associated with ''generatedaddress''.
Convert that private key into a Bitcoin address, honoring the compression preference specified in the encrypted key.
Hash the Bitcoin address, and verify that ''addresshash'' from the encrypted private key record matches the hash. If not, report that the passphrase entry was incorrect.
==Backwards compatibility== Backwards compatibility is minimally applicable since this is a new standard that at most extends [[Wallet Import Format]]. It is assumed that an entry point for private key data may also accept existing formats of private keys (such as hexadecimal and [[Wallet Import Format]]); this draft uses a key format that cannot be mistaken for any existing one and preserves auto-detection capabilities.
==Suggestions for implementers of proposal with alt-chains== If this proposal is accepted into alt-chains, it is requested that the unused flag bytes not be used for denoting that the key belongs to an alt-chain.
Alt-chain implementers should exploit the address hash for this purpose. Since each operation in this proposal involves hashing a text representation of a coin address which (for Bitcoin) includes the leading '1', an alt-chain can easily be denoted simply by using the alt-chain's preferred format for representing an address. Alt-chain implementers may also change the prefix such that encrypted addresses do not start with "6P".
==Discussion item: scrypt parameters== This proposal leaves the scrypt parameters up in the air. The following items are proposed for consideration:
The main goal of scrypt is to reduce the feasibility of brute force attacks. It must be assumed that an attacker will be able to use an efficient implementation of scrypt. The parameters should force a highly efficient implementation of scrypt to wait a decent amount of time to slow attacks.
On the other hand, an unavoidably likely place where scrypt will be implemented is using slow interpreted languages such as javascript. What might take milliseconds on an efficient scrypt implementation may take seconds in javascript.
It is believed, however, that someone using a javascript implementation is probably dealing with codes by hand, one at a time, rather than generating or processing large batches of codes. Thus, a wait time of several seconds is acceptable to a user.
A private key redemption process that forces a server to consume several seconds of CPU time would discourage implementation by the server owner, because they would be opening up a denial of service avenue by inviting users to make numerous attempts to invoke the redemption process. However, it's also feasible for the server owner to implement his redemption process in such a way that the decryption is done by the user's browser, offloading the task from his own server (and providing another reason why the chosen scrypt parameters should be tolerant of javascript-based decryptors).
The preliminary values of 16384, 8, and 8 are hoped to offer the following properties:

Encryption/decryption in javascript requiring several seconds per operation
Use of the parallelization parameter provides a modest opportunity for speedups in environments where concurrent threading is available - such environments would be selected for processes that must handle bulk quantities of encryption/decryption operations.  Estimated time for an operation is in the tens or hundreds of milliseconds.

==Reference implementation== Added to alpha version of Casascius Bitcoin Address Utility for Windows available at:

via https: https://casascius.com/btcaddress-alpha.zip
at github: https://github.com/casascius/Bitcoin-Address-Utility

Click "Tools" then "PPEC Keygen" (provisional name)
==Test vectors==
===No compression, no EC multiply===
Test 1: *Passphrase: TestingOneTwoThree *Encrypted: 6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg *Unencrypted (WIF): 5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR *Unencrypted (hex): CBF4B9F70470856BB4F40F80B87EDB90865997FFEE6DF315AB166D713AF433A5
Test 2: *Passphrase: Satoshi *Encrypted: 6PRNFFkZc2NZ6dJqFfhRoFNMR9Lnyj7dYGrzdgXXVMXcxoKTePPX1dWByq *Unencrypted (WIF): 5HtasZ6ofTHP6HCwTqTkLDuLQisYPah7aUnSKfC7h4hMUVw2gi5 *Unencrypted (hex): 09C2686880095B1A4C249EE3AC4EEA8A014F11E6F986D0B5025AC1F39AFBD9AE
Test 3: *Passphrase ϓ␀𐐀💩 (\u03D2\u0301\u0000\U00010400\U0001F4A9; [http://codepoints.net/U+03D2 GREEK UPSILON WITH HOOK], [http://codepoints.net/U+0301 COMBINING ACUTE ACCENT], [http://codepoints.net/U+0000 NULL], [http://codepoints.net/U+10400 DESERET CAPITAL LETTER LONG I], [http://codepoints.net/U+1F4A9 PILE OF POO]) *Encrypted key: 6PRW5o9FLp4gJDDVqJQKJFTpMvdsSGJxMYHtHaQBF3ooa8mwD69bapcDQn *Bitcoin Address: 16ktGzmfrurhbhi6JGqsMWf7TyqK9HNAeF *Unencrypted private key (WIF): 5Jajm8eQ22H3pGWLEVCXyvND8dQZhiQhoLJNKjYXk9roUFTMSZ4

''Note:'' The non-standard UTF-8 characters in this passphrase should be NFC normalized to result in a passphrase of 0xcf9300f0909080f09f92a9 before further processing

===Compression, no EC multiply===
Test 1: *Passphrase: TestingOneTwoThree *Encrypted: 6PYNKZ1EAgYgmQfmNVamxyXVWHzK5s6DGhwP4J5o44cvXdoY7sRzhtpUeo *Unencrypted (WIF): L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP *Unencrypted (hex): CBF4B9F70470856BB4F40F80B87EDB90865997FFEE6DF315AB166D713AF433A5
Test 2: *Passphrase: Satoshi *Encrypted: 6PYLtMnXvfG3oJde97zRyLYFZCYizPU5T3LwgdYJz1fRhh16bU7u6PPmY7 *Unencrypted (WIF): KwYgW8gcxj1JWJXhPSu4Fqwzfhp5Yfi42mdYmMa4XqK7NJxXUSK7 *Unencrypted (hex): 09C2686880095B1A4C249EE3AC4EEA8A014F11E6F986D0B5025AC1F39AFBD9AE
===EC multiply, no compression, no lot/sequence numbers===
Test 1: *Passphrase: TestingOneTwoThree *Passphrase code: passphrasepxFy57B9v8HtUsszJYKReoNDV6VHjUSGt8EVJmux9n1J3Ltf1gRxyDGXqnf9qm *Encrypted key: 6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX *Bitcoin address: 1PE6TQi6HTVNz5DLwB1LcpMBALubfuN2z2 *Unencrypted private key (WIF): 5K4caxezwjGCGfnoPTZ8tMcJBLB7Jvyjv4xxeacadhq8nLisLR2 *Unencrypted private key (hex): A43A940577F4E97F5C4D39EB14FF083A98187C64EA7C99EF7CE460833959A519
Test 2: *Passphrase: Satoshi *Passphrase code: passphraseoRDGAXTWzbp72eVbtUDdn1rwpgPUGjNZEc6CGBo8i5EC1FPW8wcnLdq4ThKzAS *Encrypted key: 6PfLGnQs6VZnrNpmVKfjotbnQuaJK4KZoPFrAjx1JMJUa1Ft8gnf5WxfKd *Bitcoin address: 1CqzrtZC6mXSAhoxtFwVjz8LtwLJjDYU3V *Unencrypted private key (WIF): 5KJ51SgxWaAYR13zd9ReMhJpwrcX47xTJh2D3fGPG9CM8vkv5sH *Unencrypted private key (hex): C2C8036DF268F498099350718C4A3EF3984D2BE84618C2650F5171DCC5EB660A
===EC multiply, no compression, lot/sequence numbers===
Test 1: *Passphrase: MOLON LABE *Passphrase code: passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX *Encrypted key: 6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j *Bitcoin address: 1Jscj8ALrYu2y9TD8NrpvDBugPedmbj4Yh *Unencrypted private key (WIF): 5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8 *Unencrypted private key (hex): 44EA95AFBF138356A05EA32110DFD627232D0F2991AD221187BE356F19FA8190 *Confirmation code: cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD *Lot/Sequence: 263183/1
Test 2: *Passphrase (all letters are Greek - test UTF-8 compatibility with this): ΜΟΛΩΝ ΛΑΒΕ *Passphrase code: passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK *Encrypted private key: 6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH *Bitcoin address: 1Lurmih3KruL4xDB5FmHof38yawNtP9oGf *Unencrypted private key (WIF): 5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D *Unencrypted private key (hex): CA2759AA4ADB0F96C414F36ABEB8DB59342985BE9FA50FAAC228C8E7D90E3006 *Confirmation code: cfrm38V8G4qq2ywYEFfWLD5Cc6msj9UwsG2Mj4Z6QdGJAFQpdatZLavkgRd1i4iBMdRngDqDs51 *Lot/Sequence: 806938/1`

#7


Add Docker image for cargo-pgo

Hey Jakub! Sorry for such a late PR!
To deploy an image with your Docker Hub account, you may need to generate an access token and then add your account and token to this repo's secrets.
I've tested the new workflow with a test-use repository and it works well. These repositories will be deleted once this PR is merged :smile:

Hi, thanks a lotfor the PR!
Regarding the LLVM installation approach, have you tried that BOLT indeed works, both for instrumentation and then for generating samples? I haven't tried with LLVM 18, but with previous versions, the installed bolt-XY package from Ubuntu haven't been functioning properly (https://github.com/Kobzol/cargo-pgo/issues/31). It was detected, but failed during instrumentation/sample gathering.

Yeah the BOLT also works well. You can test it locally using cargo-pgo itself in these steps:
Firstly, build the image and get into the container:
git clone https://github.com/bioinformatist/cargo-pgo.git && cd cargo-pgo
docker build -t pgo .
docker run --entrypoint bash -v $(pwd):/workdir --rm -it pgo

Then in the container:
cargo pgo build
/workdir/target/x86_64-unknown-linux-gnu/release/cargo-pgo pgo info
cargo pgo bolt build --with-pgo
/workdir/target/x86_64-unknown-linux-gnu/release/cargo-pgo-bolt-instrumented pgo info
cargo pgo bolt optimize --with-pgo

I believe the issue lies in the suffix of the binaries (like the -18 in merge-fdata-18) and the incorrect location of the linking library (.a), which caused the bolt-XY package from Ubuntu to not work. The soft linking (ln -s) in Dockerfile can fix it. While compiling LLVM from the source code is a more elegant way, it spends more time, which maybe not ideal for CI.

Got that! I'll finish it ASAP.


RedisChannelLayer.receive runs forever

RedisChannelLayer.receive, that was reworked in #43, now hangs forever if called with block. That was not the case in the previous version (it returned (None, None). This prevents channels Worker from exiting if termed is set to true (e.g. in the signal handler).

The ASGI spec says "block means that the call can take as long as it likes", so this is valid behaviour. What needs fixing here is the channels Worker; if you could file a bug against the channels project we can fix it over there so an interrupt correctly yanks it out of any receive call.

Done. Maybe I will try my luck at fixing this in channels tomorrow. Thanks for your work, guys!

@andrewgodwin maybe the ASGI spec should be reworded, because in the same paragraph there is the sentence: "If block is True, then it will not return until after a built-in timeout or a message arrives;"
For me that means that it should eventually return after a non infinite timeout.

Yes, I will clarify that paragraph so it's clear it is allowed to block forever.


Remove upper case constants

I have merged the change, so please go ahead and publish it.
Cheers

This isn't published yet AFAIK
On Tue, May 22, 2018 at 6:02 AM Lasse R.H. Nielsen<EMAIL_ADDRESS>wrote:

I have merged the change, so please go ahead and publish it.
Cheers
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dart-lang/http_io/pull/63#issuecomment-390981370, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AABCitBiVVFqmkuen4UBuxKrwAsdasE8ks5t1AxpgaJpZM4TQH5t
.


Doron/explicit tool definition option

LMK if it looks good I'll add test and readme.

the general idea looks good. I wonder though if the right approach in terms of usability of the this library is to have the use input a list of tools? and then separately specify the tool she actually wants to run. an alternative might be to have the user set some flag - say --skip_tool_scanning and then specify the tool of choice by its fully qualified name, including module etc?

@noamBarkai the user doesn't specify a list of tools. the developer does.
The user only specify which tool he wants to use.

the general idea looks good. I wonder though if the right approach in terms of usability of the this library is to have the use input a list of tools? and then separately specify the tool she actually wants to run. an alternative might be to have the user set some flag - say --skip_tool_scanning and then specify the tool of choice by its fully qualified name, including module etc?

@noamBarkai the user doesn't specify a list of tools. the developer does.
The user only specify which tool he wants to use.


Beads in a theme's css rule are not processed

My test are with a component that extends a Group and has a css that declared a "iViewBead", the bead is a MXML Bead that creates a simple button

Beads in themes are not working, only work if both (component and viewbead) are located in the same lib. Or in other terms, if the component is in a lib and its viewbead is in the theme that doesn't work. I think this is a bug and that case is not considered in the compiler.

If I assign a Bead in a lib, and one in a theme, only the one in the lib is created at runtime. If I remove the one in lib, no bead is created. So the one in the theme is compiled and goes in the theme but is not processed in the final app.

With 1) working, I should be able to have a viewbead in the lib and a viewbead in the theme, and the one in theme be the one used in final app.
(the one in the lib should not be considered). As well if I have a css rule in the final App that defines another viewbead, that should be processed as well.

This is working for me.  The git branch seems to be confused so I'm afraid to check stuff in, but I added the LabelViewBead to the JewelTheme by adding it to defaults.css
j|Label {
IBeadView: ClassReference("org.apache.royale.jewel.beads.views.LabelViewBead");
}
and adding it to jeweltheme-manifest.xml

and added Jewel Label to the example:
        <j:Label text="Hello World" />

And the output in App.js contained:
"org.apache.royale.jewel.Label",
function() {this["iBeadView"] = org.apache.royale.jewel.beads.views.LabelViewBead},

Hi Alex, I final could test this and now is working, don't know if is some of the fixes you did in the last days or something wrong on my side. But finally we have this working and seems a very powerful feature.
Thanks!


Report from hpmaennicke that even if powerlevels prevent normal users from talking in a room, iOS users can do so (or at least appear to do so).

Are we forgetting to lock out MessageComposer if the user has no permission to talk?

Are we forgetting to lock out MessageComposer if the user has no permission to talk?

yes. Android shows this:


Updated sbt-js-engine to 1.1.3

Hello,
I had trouble compiling typescript code with features from 1.6 version (eg. abstract classes) and noticed that the sbt-js-engine in a convoluted way added typescript-node 1.5.3 version to the project and the plugin used this version instead of 1.6.2. Updating the dependency brings 1.6 features.
Regards,
Marcin Bablok

On principal, I like the changes.  But I would like to learn more about why the dependency on the older version of sbt-js-engine eventually led to the wrong version of the typescript compiler to be used. Do you have any more information as to how this happened? Do you have a repro case that we can turn into a test?

The reasons for the strange and 'very transient' dependency are unclear to me. The https://github.com/jrudolph/sbt-dependency-graph plugin did not show it. I browsed the sbt-js-engine code, and its plugins, but found nothing, and unfortunately do not have time to investigate further.
But I noticed that after removing typescript-node version 1.5.3 from my ivy2 cache and reloading a test project including Your plugin, the 1.5.3 was downloaded again, and simple 1.6 code:
abstract class A {
  foo(): number { return this.bar(); }
  abstract bar(): number;
}

did not compile.
I changed the js-engine plugin version and it compiles, thus is using the correct typescript node version.

Would you like me to prepare a test project for this?


README.md

cleaner PRs here that need to be reviewed and merged in following order:
PR https://github.com/Xcov19/mhc-fe/pull/34
PR https://github.com/Xcov19/mhc-fe/pull/36


Complete copy edit pass

@rotycenh

OPS Build status updates of commit 02eb626:
:clock10: Preparing: average preparing time is 46 sec(s)

OPS Build status updates of commit 02eb626:
:clock10: Incremental building: average incremental building time is 22 sec(s)

OPS Build status updates of commit 02eb626:
:warning: Validation status: warnings

File
Status
Preview URL
Details

bread/toc.json
:warning:Warning

Details

toc.json
:warning:Warning

Details

building-blocks/extending-templates/toc.json
:warning:Warning

Details

docs/cloud-adoption/governance/cost-management/template.md
:white_check_mark:Succeeded
View

bread/toc.json

[Warning] Error happen when converting bread/toc.json to Pdf. Details: Could not find a part of the path 'T:\3n4q\bread\toc.json'.

toc.json

[Warning] Error happen when converting toc.json to Pdf. Details: Could not find file 'T:\3n4q\toc.json'.

building-blocks/extending-templates/toc.json

[Warning] Error happen when converting building-blocks/extending-templates/toc.json to Pdf. Details: Could not find a part of the path 'T:\3n4q\building-blocks\extending-templates\toc.json'.

For more details, please refer to the build report.
Note: If you changed an existing file name or deleted a file, broken links in other files to the deleted or renamed file are listed only in the full build report.

 Details: Could not find a part of the path 'T:\ibnh\building-blocks\extending-templates\toc.json'.

bread/toc.json

[Warning] Error happen when converting bread/toc.json to Pdf. Details: Could not find a part of the path 'T:\ibnh\bread\toc.json'.

toc.json

[Warning] Error happen when converting toc.json to Pdf. Details: Could not find file 'T:\ibnh\toc.json'.

For more details, please refer to the build report.
Note: If you changed an existing file name or deleted a file, broken links in other files to the deleted or renamed file are listed only in the full build report.


Mounting volume to browser pod

How to mount openshift volume to browser container?
$ oc get pvc
NAME             STATUS    VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
edge18           Bound     edge18           25Gi       RWO                           8m
ie11             Bound     ie11             25Gi       RWO                           9m

I tried without luck:
  "ie": {
    "default": "11",
        "versions": {
        "11": {
          "image": "emilorol/vnc_qemu:latest",
          "port": "4444",
          "path": "/",
          "volumes":["ie11:/images"]
        }
      }
    },
  "edge": {
    "default": "18",
        "versions": {
        "18": {
          "image": "emilorol/vnc_qemu:latest",
          "port": "4444",
          "path": "/",
          "volumes":["edge18:/images"]
        }
      }
    }

The reasoning behind this is to use OpenShift volumes to hold the windows images for example when testing internet explorer or edge browsers.

Only hostPath volumes are supported at the moment... In my opinion it is
not good idea to use volumes at all. It is better to strip down windows
images with special utilities. For ex it is possible to create 3.5Gb
windows 7 image...
пт, 20 сент. 2019 г., 18:08 Emil Orol<EMAIL_ADDRESS>
The reasoning behind this is to use OpenShift volumes to hold the windows
images for example when testing internet explorer or edge browsers.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/aerokube/moon/issues/158?email_source=notifications&email_token=AAKY23IZ2V4RISRS73QOH23QKTRQVA5CNFSM4IYS4JGKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7G7VOI#issuecomment-533592761,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAKY23NSBPAQFOU5FK42XDDQKTRQVANCNFSM4IYS4JGA
.

Ok, thank you for the clarification. Keep up the good work.


Gelbooru image grab fails because grabber takes images from incorrect image server

Bug description
Grabber tries to download images from img1 (doesn't exist), while they're hosted on img2. Log entries say (Host img1.gelbooru.com not found)
Steps to reproduce
Grab gelbooru tag "amashun", and compare image servers gelbooru presents https://img2.gelbooru.com/images/*** (without img* also works)
to what Grabber tries to download
https://img1.gelbooru.com/images/***
Expected behavior
Images downloaded from correct server.

What API are you using? (you can see that in the logs)
Because the URLs used for Gelbooru are taken straight from their XML API (ex: https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=20&pid=0&tags=), so if it's the wrong server, that might be a bug on their end?
Note that I couldn't reproduce the issue on either HTML or XML sources.

I noticed some skips when downloading artists batches day or two ago. The problem is with pictures that have a tag "loli" or "shota", maybe some other tags too.

I started having the same problem today aswell.

[17:27:13.161][Info] Updating checkboxes.
[17:27:13.166][Info] [gelbooru.com] Logging in...
[17:27:13.166][Info] [gelbooru.com] Login finished: success.
[17:27:13.166][Info] Updating checkboxes.
[17:27:13.171][Info] Monitoring starting
[17:27:13.276][Info] Monitoring tick
[17:27:13.276][Info] Monitoring finished
[17:27:22.966][Info] Loading 197 downloads
[17:27:55.169][Info] Loading results...
[17:27:55.174][Info] [gelbooru.com][Html] Loading page `https://gelbooru.com/index.php?page=post&s=list&tags=amashun&pid=0`
[17:27:55.174][Info] [gelbooru.com][Xml] Loading page `https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=20&pid=0&tags=amashun`
[17:27:55.944][Info] [gelbooru.com][Xml] Receiving page `https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=20&pid=0&tags=amashun`
[17:27:55.959][Info] [gelbooru.com][Xml] Parsed page `https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=20&pid=0&tags=amashun`: 20 images (20), 0 tags (348), 155 total (155), 8 pages (8)
[17:27:56.079][Info] [gelbooru.com][Html] Receiving page `https://gelbooru.com/index.php?page=post&s=list&tags=amashun&pid=0`
[17:27:56.099][Info] [gelbooru.com][Html] Parsed page `https://gelbooru.com/index.php?page=post&s=list&tags=amashun&pid=0`: 42 images (42), 74 tags (74), 155 total (155), 4 pages (4)
[17:28:05.186][Info] Batch download started.
[17:28:05.239][Info] [gelbooru.com][Xml] Loading page `https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=155&pid=0&tags=amashun`
[17:28:06.225][Info] [gelbooru.com][Xml] Receiving page `https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=155&pid=0&tags=amashun`
[17:28:06.336][Info] [gelbooru.com][Xml] Parsed page `https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=155&pid=0&tags=amashun`: 155 images (155), 0 tags (1375), 155 total (155), 1 pages (1)
[17:28:06.337][Info] All images' urls have been received (155).
[17:28:06.343][Info] Loading image from `https://img2.gelbooru.com/images/9a/86/9a8623e5faf19c536736e6ff70be2050.jpg` 1
[17:28:06.344][Info] File already exists: `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.30.31.000.jpg`
[17:28:06.359][Info] Loading image from `https://img2.gelbooru.com/images/3f/d6/3fd67147bbea5b32bc74a37e03a7fdd2.jpg` 1
[17:28:06.360][Info] File already exists: `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.30.15.000.jpg`
[17:28:06.364][Info] Loading image from `https://img1.gelbooru.com/images/a1/a9/a1a91d05da2649d3bef2c1f38ab6d9ec.jpg` 1
[17:28:06.365][Info] Loading and saving image from `https://img1.gelbooru.com/images/a1/a9/a1a91d05da2649d3bef2c1f38ab6d9ec.jpg` in `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.30.12.000.jpg`
[17:28:06.367][Info] Loading image from `https://img1.gelbooru.com/images/e9/d8/e9d82fa150ef26b15c143110e0b99a16.jpeg` 2
[17:28:06.368][Info] Loading and saving image from `https://img1.gelbooru.com/images/e9/d8/e9d82fa150ef26b15c143110e0b99a16.jpeg` in `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.50.36.000.jpg`
[17:28:06.369][Info] Loading image from `https://img1.gelbooru.com/images/86/59/86598e63a657075bdec947704b271e12.jpeg` 3
[17:28:06.370][Info] Loading and saving image from `https://img1.gelbooru.com/images/86/59/86598e63a657075bdec947704b271e12.jpeg` in `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.50.23.000.jpg`
[17:28:06.370][Info] Loading image from `https://img1.gelbooru.com/images/91/b0/91b03b563cb3aba4e7e4cbc603c4e70f.jpeg` 4
[17:28:06.371][Info] Loading and saving image from `https://img1.gelbooru.com/images/91/b0/91b03b563cb3aba4e7e4cbc603c4e70f.jpeg` in `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.50.07.000.jpg`
[17:28:06.372][Info] Loading image from `https://img2.gelbooru.com/images/af/3a/af3a92787e28d6abb28aca4d2dc18573.png` 5
[17:28:06.373][Info] File already exists: `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.44.27.000.png`
[17:28:06.378][Info] Loading image from `https://img2.gelbooru.com/images/68/60/6860302e9a328eaf81789d8955158bb1.jpeg` 5
[17:28:06.379][Info] File already exists: `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.11.09.000.jpg`
[17:28:06.384][Info] Loading image from `https://img1.gelbooru.com/images/ce/ff/ceffc1b2ca5617273250205f76cc71d5.png` 5
[17:28:06.386][Info] Loading and saving image from `https://img1.gelbooru.com/images/ce/ff/ceffc1b2ca5617273250205f76cc71d5.png` in `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.09.11.000.png`
[17:28:06.386][Info] Loading image from `https://img1.gelbooru.com/images/5d/46/5d468e230cdf5acd1fbdd190a6373c0d.jpeg` 6
[17:28:06.387][Info] Loading and saving image from `https://img1.gelbooru.com/images/5d/46/5d468e230cdf5acd1fbdd190a6373c0d.jpeg` in `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.08.49.000.jpg`
[17:28:06.388][Info] Loading image from `https://img2.gelbooru.com/images/e0/1a/e01abf8f22cb6a3fed4ead988df1606a.jpeg` 7
[17:28:06.389][Info] File already exists: `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.17.58.000.jpg`
[17:28:06.397][Info] Loading image from `https://img1.gelbooru.com/images/67/3d/673d28dde545c146eeb7cce5ec3cf15f.jpeg` 7
[17:28:06.398][Info] Loading and saving image from `https://img1.gelbooru.com/images/67/3d/673d28dde545c146eeb7cce5ec3cf15f.jpeg` in `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.08.39.000.jpg`
[17:28:06.399][Info] Loading image from `https://img3.gelbooru.com/images/b9/89/b989a629d96d973a8b04a1ae08af6b7e.jpeg` 8
[17:28:06.400][Info] File already exists: `G:\Grabber\Pictures\amashun\2<IP_ADDRESS>.50.26.000.jpg`
[17:28:06.403][Error] Network error for the image: `https://img1.gelbooru.com/images/a1/a9/a1a91d05da2649d3bef2c1f38ab6d9ec.jpg`: 3 (Host img1.gelbooru.com not found)
[17:28:06.404][Error] Network error for the image: `https://img1.gelbooru.com/images/e9/d8/e9d82fa150ef26b15c143110e0b99a16.jpeg`: 3 (Host img1.gelbooru.com not found)
[17:28:06.405][Error] Network error for the image: `https://img1.gelbooru.com/images/86/59/86598e63a657075bdec947704b271e12.jpeg`: 3 (Host img1.gelbooru.com not found)
[17:28:06.407][Error] Network error for the image: `https://img1.gelbooru.com/images/91/b0/91b03b563cb3aba4e7e4cbc603c4e70f.jpeg`: 3 (Host img1.gelbooru.com not found)

Problem seems solved by itself for me.


Renaming package names and groupIds

HARD BRAKING CHANGES
This pull request changes the package name from de.dytanic.cloudnet* to eu.cloudnetservice.v2.*
Older API,plugins and Modules and more dosen't worke anymore.

I have local tested the maven, running fine. But not here ?

Given that version 2.2 is mostly breaking, forcing everything to be broken, should be fine

After reassuring with the rest of the team, we would like to use eu.cloudnetservice.cloudnet.v2 for CloudNet V2


bcachefs: 2022-09-28 -> 2022-10-12

Description of changes
The usual update.
Tests pass. (Remove zfs from nixos/profiles/base.nix if you want to test it yourself.)
Error on commits past this for bcachefs-tools regarding prt_printf, so not the latest.

Things done

Built on platform(s)

[x] x86_64-linux
[ ] aarch64-linux
[ ] x86_64-darwin
[ ] aarch64-darwin

[ ] For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
[x] Tested, as applicable:

NixOS test(s) (look inside nixos/tests)
and/or package tests
or, for functions and "core" functionality, tests in lib/tests or pkgs/test
made sure NixOS tests are linked to the relevant packages

[ ] Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
[x] Tested basic functionality of all binary files (usually in ./result/bin/)
22.11 Release Notes (or backporting 22.05 Release notes)

[ ] (Package updates) Added a release notes entry if the change is major or breaking
[ ] (Module updates) Added a release notes entry if the change is significant
[ ] (Module addition) Added a release notes entry if adding a new NixOS module
[ ] (Release notes changes) Ran nixos/doc/manual/md-to-db.sh to update generated release notes

[x] Fits CONTRIBUTING.md.

already updated to 2022-10-31 in #198992 / d666b6c19a486862ad3676fea5f9816e52b9dbe8 cc @lovesegfault


skillmap hover render error [safari]

Describe the bug
not a regression from live
skillmap render error in safari 14.x; when hovering over any skillmap icon it doubles the maps rendering offset by a bit:

This only appears to happen when within ~ 30-40px of full screen on my macbook pro 15"; if you make the window smaller / etc it doesn't repro
To Reproduce
Steps to reproduce the behavior:

Go to arcade.makecode.com/---skillmap in mac / safari with full screen
make window full screen
hover over an icon on the screen
See error

Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
should not look weird
Desktop (please complete the following information):

OS: mac
Browser safari
Version 14

Dupe of https://github.com/microsoft/pxt-arcade/issues/3823


Dedicated Disk for OpenSprites

When OpenSprites goes into production I may be able to attach a dedicated storage disk to the host node, and then symlink a directory in the OpenSprites webspace to that drive.
It should in theory provide a better R/W speed as well as the benefit of isolating user data from the main node's disk.
Thoughts? Obviously code will need to be adjusted to write data to that specific "disk directory".

That would certainly boost response time for the site! While at the moment, a solid site is more of a priority, speed will be once the site has users start uploading and downloading. When you say disk, I'm guessing you mean a virtual one on a physical SSD or HDD?

In this case it'd be a VHD attached to the Gwiddle Node, however the difference being is that the disk will be on an SSD-based storage node.

Ok, that sounds great!

Ties in with #145. Changing milestone.


Created a step for caching the maven dependencies

Closes #3

Merging the changes for caching the maven dependencies in the workflow.
Closes #3